Fossil

Check-in [6f95bf643a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:merge trunk
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | multi-thread
Files: files | file ages | folders
SHA1: 6f95bf643abee09f5dd807d778104c15e7d78ac1
User & Date: jan.nijtmans 2014-11-28 15:31:00.000
Context
2014-11-28
17:33
merge trunk ... (check-in: 59cde7bb12 user: jan.nijtmans tags: multi-thread)
15:31
merge trunk ... (check-in: 6f95bf643a user: jan.nijtmans tags: multi-thread)
15:11
Restore the built-in SQLite to version 3.8.8 after fixing the fragmentation size corruption problem. ... (check-in: 21b30fc023 user: drh tags: trunk)
2014-09-26
14:04
merge trunk ... (check-in: 9ba4ebaa66 user: jan.nijtmans tags: multi-thread)
Changes
Unified Diff Ignore Whitespace Patch
Changes to Dockerfile.
22
23
24
25
26
27
28
29
30
31
32
33
34
35

### Build is done, remove modules no longer needed
RUN yum remove -y gcc make zlib-devel openssl-devel tcl-devel && yum clean all

USER fossil

ENV HOME /opt/fossil

RUN fossil new --empty -A admin /opt/fossil/repository.fossil
RUN fossil user password -R /opt/fossil/repository.fossil admin admin
RUN fossil cache init -R /opt/fossil/repository.fossil

EXPOSE 8080

CMD ["/usr/bin/fossil", "server", "/opt/fossil/repository.fossil"]








|






>
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
### Build is done, remove modules no longer needed
RUN yum remove -y gcc make zlib-devel openssl-devel tcl-devel && yum clean all

USER fossil

ENV HOME /opt/fossil

RUN fossil new --docker -A admin /opt/fossil/repository.fossil
RUN fossil user password -R /opt/fossil/repository.fossil admin admin
RUN fossil cache init -R /opt/fossil/repository.fossil

EXPOSE 8080

CMD ["/usr/bin/fossil", "server", "/opt/fossil/repository.fossil"]

Changes to Makefile.in.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#### Tcl shell for use in running the fossil testsuite.  If you do not
#    care about testing the end result, this can be blank.
#
TCLSH = tclsh

LIB =	@LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@
TCC +=	@EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H -D_HAVE_SQLITE_CONFIG_H
INSTALLDIR = $(DESTDIR)@prefix@/bin
USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@
FOSSIL_ENABLE_MINIZ = @FOSSIL_ENABLE_MINIZ@

include $(SRCDIR)/main.mk

distclean: clean







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#### Tcl shell for use in running the fossil testsuite.  If you do not
#    care about testing the end result, this can be blank.
#
TCLSH = tclsh

LIB =	@LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@
TCCFLAGS =	@EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H -D_HAVE_SQLITE_CONFIG_H
INSTALLDIR = $(DESTDIR)@prefix@/bin
USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@
FOSSIL_ENABLE_MINIZ = @FOSSIL_ENABLE_MINIZ@

include $(SRCDIR)/main.mk

distclean: clean
Changes to auto.def.
276
277
278
279
280
281
282

283
284
285
286
287
288
289
    if {[string match *mingw* [get-define host]]} {
        define-append LIBS -lwsock32
    }
}
cc-check-function-in-lib iconv iconv
cc-check-functions utime
cc-check-functions usleep


# Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
if {![cc-check-functions getloadavg]} {
  define FOSSIL_OMIT_LOAD_AVERAGE 1
  msg-result "Load average support unavailable"
}








>







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
    if {[string match *mingw* [get-define host]]} {
        define-append LIBS -lwsock32
    }
}
cc-check-function-in-lib iconv iconv
cc-check-functions utime
cc-check-functions usleep
cc-check-functions strchrnul

# Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
if {![cc-check-functions getloadavg]} {
  define FOSSIL_OMIT_LOAD_AVERAGE 1
  msg-result "Load average support unavailable"
}

Changes to src/allrepo.c.
96
97
98
99
100
101
102


103
104
105
106
107
108
109
**               caution should be exercised with this command because its
**               effects cannot be undone.  Use of the --dry-run option to
**               carefully review the local checkouts to be operated upon
**               and the --whatif option to carefully review the files to
**               be deleted beforehand is highly recommended.  The command
**               line options supported by the clean command itself, if any
**               are present, are passed along verbatim.


**
**    extras     Shows "extra" files from all local checkouts.  The command
**               line options supported by the extra command itself, if any
**               are present, are passed along verbatim.
**
**    ignore     Arguments are repositories that should be ignored by
**               subsequent clean, extras, list, pull, push, rebuild, and







>
>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
**               caution should be exercised with this command because its
**               effects cannot be undone.  Use of the --dry-run option to
**               carefully review the local checkouts to be operated upon
**               and the --whatif option to carefully review the files to
**               be deleted beforehand is highly recommended.  The command
**               line options supported by the clean command itself, if any
**               are present, are passed along verbatim.
**
**    dbstat     Run the "dbstat" command on all repositories.
**
**    extras     Shows "extra" files from all local checkouts.  The command
**               line options supported by the extra command itself, if any
**               are present, are passed along verbatim.
**
**    ignore     Arguments are repositories that should be ignored by
**               subsequent clean, extras, list, pull, push, rebuild, and
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
**               --randomize options are not supported.
**
**    sync       Run a "sync" on all repositories.  Only the --verbose
**               option is supported.
**
**    setting    Run the "setting", "set", or "unset" commands on all
**    set        repositories.  These command are particularly useful in
**    unset      conjunection with the "max-loadavg" setting which cannot
**               otherwise be set globally.
**
** Repositories are automatically added to the set of known repositories
** when one of the following commands are run against the repository:
** clone, info, pull, push, or sync.  Even previously ignored repositories
** are added back to the list of repositories by these commands.
**







|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
**               --randomize options are not supported.
**
**    sync       Run a "sync" on all repositories.  Only the --verbose
**               option is supported.
**
**    setting    Run the "setting", "set", or "unset" commands on all
**    set        repositories.  These command are particularly useful in
**    unset      conjunction with the "max-loadavg" setting which cannot
**               otherwise be set globally.
**
** Repositories are automatically added to the set of known repositories
** when one of the following commands are run against the repository:
** clone, info, pull, push, or sync.  Even previously ignored repositories
** are added back to the list of repositories by these commands.
**
188
189
190
191
192
193
194






195
196
197
198
199
200
201
    collect_argument(&extra, "force","f");
    collect_argument_value(&extra, "ignore");
    collect_argument_value(&extra, "keep");
    collect_argument(&extra, "temp",0);
    collect_argument(&extra, "verbose","v");
    collect_argument(&extra, "whatif",0);
    useCheckouts = 1;






  }else if( strncmp(zCmd, "extras", n)==0 ){
    if( showFile ){
      zCmd = "extras --chdir";
    }else{
      zCmd = "extras --header --chdir";
    }
    collect_argument(&extra, "abs-paths",0);







>
>
>
>
>
>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    collect_argument(&extra, "force","f");
    collect_argument_value(&extra, "ignore");
    collect_argument_value(&extra, "keep");
    collect_argument(&extra, "temp",0);
    collect_argument(&extra, "verbose","v");
    collect_argument(&extra, "whatif",0);
    useCheckouts = 1;
  }else if( strncmp(zCmd, "dbstat", n)==0 ){
    zCmd = "dbstat --omit-version-info -R";
    showLabel = 1;
    quiet = 1;
    collect_argument(&extra, "brief", "b");
    collect_argument(&extra, "db-check", 0);
  }else if( strncmp(zCmd, "extras", n)==0 ){
    if( showFile ){
      zCmd = "extras --chdir";
    }else{
      zCmd = "extras --header --chdir";
    }
    collect_argument(&extra, "abs-paths",0);
247
248
249
250
251
252
253
254


255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
    quiet = 1;
  }else if( strncmp(zCmd, "ignore", n)==0 ){
    int j;
    useCheckouts = find_option("ckout","c",0)!=0;
    verify_all_options();
    db_begin_transaction();
    for(j=3; j<g.argc; j++){
      char *zSql = mprintf("DELETE FROM global_config"


                           " WHERE name GLOB '%s:%q'",
                           useCheckouts?"ckout":"repo", g.argv[j]);

      if( dryRunFlag ){
        fossil_print("%s\n", zSql);
      }else{
        db_multi_exec("%s", zSql);
      }
      fossil_free(zSql);
    }
    db_end_transaction(0);
    return;
  }else if( strncmp(zCmd, "info", n)==0 ){
    zCmd = "info";
    showLabel = 1;
    quiet = 1;







|
>
>
|
|
>

|

|

|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    quiet = 1;
  }else if( strncmp(zCmd, "ignore", n)==0 ){
    int j;
    useCheckouts = find_option("ckout","c",0)!=0;
    verify_all_options();
    db_begin_transaction();
    for(j=3; j<g.argc; j++){
      Blob sql;
      blob_zero(&sql);
      blob_append_sql(&sql, 
         "DELETE FROM global_config WHERE name GLOB '%s:%q'",
         useCheckouts?"ckout":"repo", g.argv[j]
      );
      if( dryRunFlag ){
        fossil_print("%s\n", blob_sql_text(&sql));
      }else{
        db_multi_exec("%s", blob_sql_text(&sql));
      }
      blob_reset(&sql);
    }
    db_end_transaction(0);
    return;
  }else if( strncmp(zCmd, "info", n)==0 ){
    zCmd = "info";
    showLabel = 1;
    quiet = 1;
336
337
338
339
340
341
342
343
344
345
346
  ** be found, remove those names from the ~/.fossil file.
  */
  if( nToDel>0 ){
    const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
    if( dryRunFlag ){
      fossil_print("%s\n", zSql);
    }else{
      db_multi_exec(zSql);
    }
  }
}







|



347
348
349
350
351
352
353
354
355
356
357
  ** be found, remove those names from the ~/.fossil file.
  */
  if( nToDel>0 ){
    const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
    if( dryRunFlag ){
      fossil_print("%s\n", zSql);
    }else{
      db_multi_exec("%s", zSql /*safe-for-%s*/ );
    }
  }
}
Changes to src/attach.c.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  const char *zTkt = P("tkt");
  Blob sql;
  Stmt q;

  if( zPage && zTkt ) zTkt = 0;
  login_check_credentials();
  blob_zero(&sql);
  blob_appendf(&sql,
     "SELECT datetime(mtime%s), src, target, filename,"
     "       comment, user,"
     "       (SELECT uuid FROM blob WHERE rid=attachid), attachid"
     "  FROM attachment",
     timeline_utc()
  );
  if( zPage ){
    if( g.perm.RdWiki==0 ) login_needed();
    style_header("Attachments To %h", zPage);
    blob_appendf(&sql, " WHERE target=%Q", zPage);
  }else if( zTkt ){
    if( g.perm.RdTkt==0 ) login_needed();
    style_header("Attachments To Ticket %S", zTkt);
    blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt);
  }else{
    if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
    style_header("All Attachments");
  }
  blob_appendf(&sql, " ORDER BY mtime DESC");
  db_prepare(&q, "%s", blob_str(&sql));
  @ <ol>
  while( db_step(&q)==SQLITE_ROW ){
    const char *zDate = db_column_text(&q, 0);
    const char *zSrc = db_column_text(&q, 1);
    const char *zTarget = db_column_text(&q, 2);
    const char *zFilename = db_column_text(&q, 3);
    const char *zComment = db_column_text(&q, 4);







|









|



|




|
|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  const char *zTkt = P("tkt");
  Blob sql;
  Stmt q;

  if( zPage && zTkt ) zTkt = 0;
  login_check_credentials();
  blob_zero(&sql);
  blob_append_sql(&sql,
     "SELECT datetime(mtime%s), src, target, filename,"
     "       comment, user,"
     "       (SELECT uuid FROM blob WHERE rid=attachid), attachid"
     "  FROM attachment",
     timeline_utc()
  );
  if( zPage ){
    if( g.perm.RdWiki==0 ) login_needed();
    style_header("Attachments To %h", zPage);
    blob_append_sql(&sql, " WHERE target=%Q", zPage);
  }else if( zTkt ){
    if( g.perm.RdTkt==0 ) login_needed();
    style_header("Attachments To Ticket %S", zTkt);
    blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt);
  }else{
    if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
    style_header("All Attachments");
  }
  blob_append_sql(&sql, " ORDER BY mtime DESC");
  db_prepare(&q, "%s", blob_sql_text(&sql));
  @ <ol>
  while( db_step(&q)==SQLITE_ROW ){
    const char *zDate = db_column_text(&q, 0);
    const char *zSrc = db_column_text(&q, 1);
    const char *zTarget = db_column_text(&q, 2);
    const char *zFilename = db_column_text(&q, 3);
    const char *zComment = db_column_text(&q, 4);
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  rid = name_to_rid_www("name");
  if( rid==0 ){ fossil_redirect_home(); }
  zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
#if 0
  /* Shunning here needs to get both the attachment control artifact and
  ** the object that is attached. */
  if( g.perm.Admin ){
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
#endif
  pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
  if( pAttach==0 ) fossil_redirect_home();
  zTarget = pAttach->zAttachTarget;
  zSrc = pAttach->zAttachSrc;
  ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%s'", zSrc);
  zName = pAttach->zAttachName;
  zDesc = pAttach->zComment;
  zMime = mimetype_from_name(zName);
  fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
  if( validate16(zTarget, strlen(zTarget))
   && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zTarget)
  ){
    zTktUuid = zTarget;
    if( !g.perm.RdTkt ){ login_needed(); return; }
    if( g.perm.WrTkt ){
      style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
    }
  }else if( db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'",zTarget) ){







|












|





|







375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  rid = name_to_rid_www("name");
  if( rid==0 ){ fossil_redirect_home(); }
  zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
#if 0
  /* Shunning here needs to get both the attachment control artifact and
  ** the object that is attached. */
  if( g.perm.Admin ){
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%q'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
#endif
  pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
  if( pAttach==0 ) fossil_redirect_home();
  zTarget = pAttach->zAttachTarget;
  zSrc = pAttach->zAttachSrc;
  ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%q'", zSrc);
  zName = pAttach->zAttachName;
  zDesc = pAttach->zComment;
  zMime = mimetype_from_name(zName);
  fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
  if( validate16(zTarget, strlen(zTarget))
   && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget)
  ){
    zTktUuid = zTarget;
    if( !g.perm.RdTkt ){ login_needed(); return; }
    if( g.perm.WrTkt ){
      style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
    }
  }else if( db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'",zTarget) ){
Changes to src/blob.c.
22
23
24
25
26
27
28




29
30
31
32
33
34
35
36
37
38

39
40
41
42





43
44
45
46
47
48
49
#if defined(FOSSIL_ENABLE_MINIZ)
#  define MINIZ_HEADER_FILE_ONLY
#  include "miniz.c"
#else
#  include <zlib.h>
#endif
#include "blob.h"





#if INTERFACE
/*
** A Blob can hold a string or a binary object of arbitrary size.  The
** size changes as necessary.
*/
struct Blob {
  unsigned int nUsed;            /* Number of bytes used in aData[] */
  unsigned int nAlloc;           /* Number of bytes allocated for aData[] */
  unsigned int iCursor;          /* Next character of input to parse */

  char *aData;                   /* Where the information is stored */
  void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
};






/*
** The current size of a Blob
*/
#define blob_size(X)  ((X)->nUsed)

/*
** The buffer holding the blob data







>
>
>
>










>




>
>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#if defined(FOSSIL_ENABLE_MINIZ)
#  define MINIZ_HEADER_FILE_ONLY
#  include "miniz.c"
#else
#  include <zlib.h>
#endif
#include "blob.h"
#if defined(_WIN32)
#include <fcntl.h>
#include <io.h>
#endif

#if INTERFACE
/*
** A Blob can hold a string or a binary object of arbitrary size.  The
** size changes as necessary.
*/
struct Blob {
  unsigned int nUsed;            /* Number of bytes used in aData[] */
  unsigned int nAlloc;           /* Number of bytes allocated for aData[] */
  unsigned int iCursor;          /* Next character of input to parse */
  unsigned int blobFlags;        /* One or more BLOBFLAG_* bits */
  char *aData;                   /* Where the information is stored */
  void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
};

/*
** Allowed values for Blob.blobFlags
*/
#define BLOBFLAG_NotSQL  0x0001      /* Non-SQL text */

/*
** The current size of a Blob
*/
#define blob_size(X)  ((X)->nUsed)

/*
** The buffer holding the blob data
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
void blobReallocMalloc(Blob *pBlob, unsigned int newSize){
  if( newSize==0 ){
    free(pBlob->aData);
    pBlob->aData = 0;
    pBlob->nAlloc = 0;
    pBlob->nUsed = 0;
    pBlob->iCursor = 0;

  }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
    char *pNew = fossil_realloc(pBlob->aData, newSize);
    pBlob->aData = pNew;
    pBlob->nAlloc = newSize;
    if( pBlob->nUsed>pBlob->nAlloc ){
      pBlob->nUsed = pBlob->nAlloc;
    }
  }
}

/*
** An initializer for Blobs
*/
#if INTERFACE
#define BLOB_INITIALIZER  {0,0,0,0,blobReallocMalloc}
#endif
const Blob empty_blob = BLOB_INITIALIZER;

/*
** A reallocation function for when the initial string is in unmanaged
** space.  Copy the string to memory obtained from malloc().
*/







>














|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
void blobReallocMalloc(Blob *pBlob, unsigned int newSize){
  if( newSize==0 ){
    free(pBlob->aData);
    pBlob->aData = 0;
    pBlob->nAlloc = 0;
    pBlob->nUsed = 0;
    pBlob->iCursor = 0;
    pBlob->blobFlags = 0;
  }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
    char *pNew = fossil_realloc(pBlob->aData, newSize);
    pBlob->aData = pNew;
    pBlob->nAlloc = newSize;
    if( pBlob->nUsed>pBlob->nAlloc ){
      pBlob->nUsed = pBlob->nAlloc;
    }
  }
}

/*
** An initializer for Blobs
*/
#if INTERFACE
#define BLOB_INITIALIZER  {0,0,0,0,0,blobReallocMalloc}
#endif
const Blob empty_blob = BLOB_INITIALIZER;

/*
** A reallocation function for when the initial string is in unmanaged
** space.  Copy the string to memory obtained from malloc().
*/
215
216
217
218
219
220
221

222
223
224
225
226
227
228
  if( zData==0 ){
    *pBlob = empty_blob;
  }else{
    if( size<=0 ) size = strlen(zData);
    pBlob->nUsed = pBlob->nAlloc = size;
    pBlob->aData = (char*)zData;
    pBlob->iCursor = 0;

    pBlob->xRealloc = blobReallocStatic;
  }
}

/*
** Initialize a blob to a nul-terminated string.
** Any prior data in the blob is discarded.







>







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
  if( zData==0 ){
    *pBlob = empty_blob;
  }else{
    if( size<=0 ) size = strlen(zData);
    pBlob->nUsed = pBlob->nAlloc = size;
    pBlob->aData = (char*)zData;
    pBlob->iCursor = 0;
    pBlob->blobFlags = 0;
    pBlob->xRealloc = blobReallocStatic;
  }
}

/*
** Initialize a blob to a nul-terminated string.
** Any prior data in the blob is discarded.
246
247
248
249
250
251
252

253
254
255
256
257
258
259
void blob_zero(Blob *pBlob){
  static const char zEmpty[] = "";
  assert_blob_is_reset(pBlob);
  pBlob->nUsed = 0;
  pBlob->nAlloc = 1;
  pBlob->aData = (char*)zEmpty;
  pBlob->iCursor = 0;

  pBlob->xRealloc = blobReallocStatic;
}

/*
** Append text or data to the end of a blob.
*/
void blob_append(Blob *pBlob, const char *aData, int nData){







>







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
void blob_zero(Blob *pBlob){
  static const char zEmpty[] = "";
  assert_blob_is_reset(pBlob);
  pBlob->nUsed = 0;
  pBlob->nAlloc = 1;
  pBlob->aData = (char*)zEmpty;
  pBlob->iCursor = 0;
  pBlob->blobFlags = 0;
  pBlob->xRealloc = blobReallocStatic;
}

/*
** Append text or data to the end of a blob.
*/
void blob_append(Blob *pBlob, const char *aData, int nData){
290
291
292
293
294
295
296














297
298
299
300
301
302
303
    p->nUsed = 0;
  }
  if( p->aData[p->nUsed]!=0 ){
    blob_materialize(p);
  }
  return p->aData;
}















/*
** Return a pointer to a null-terminated string for a blob.
**
** WARNING:  If the blob is ephemeral, it might cause a '\000'
** character to be inserted into the middle of the parent blob.
** Example:  Suppose p is a token extracted from some larger







>
>
>
>
>
>
>
>
>
>
>
>
>
>







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    p->nUsed = 0;
  }
  if( p->aData[p->nUsed]!=0 ){
    blob_materialize(p);
  }
  return p->aData;
}

/*
** Return a pointer to a null-terminated string for a blob that has
** been created using blob_append_sql() and not blob_appendf().  If
** text was ever added using blob_appendf() then throw an error.
*/
char *blob_sql_text(Blob *p){
  blob_is_init(p);
  if( (p->blobFlags & BLOBFLAG_NotSQL) ){
    fossil_fatal("Internal error: Use of blob_appendf() to construct SQL text");
  }
  return blob_str(p);
}


/*
** Return a pointer to a null-terminated string for a blob.
**
** WARNING:  If the blob is ephemeral, it might cause a '\000'
** character to be inserted into the middle of the parent blob.
** Example:  Suppose p is a token extracted from some larger
669
670
671
672
673
674
675



676
677
678









679
680
681
682
683
684
685
  int i;
  for(i=0; i<nToken && blob_token(pIn, &aToken[i]); i++){}
  return i;
}

/*
** Do printf-style string rendering and append the results to a blob.



*/
void blob_appendf(Blob *pBlob, const char *zFormat, ...){
  if( pBlob ){









    va_list ap;
    va_start(ap, zFormat);
    vxprintf(pBlob, zFormat, ap);
    va_end(ap);
  }
}
void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){







>
>
>



>
>
>
>
>
>
>
>
>







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
  int i;
  for(i=0; i<nToken && blob_token(pIn, &aToken[i]); i++){}
  return i;
}

/*
** Do printf-style string rendering and append the results to a blob.
**
** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
** whereas blob_append_sql() does not.
*/
void blob_appendf(Blob *pBlob, const char *zFormat, ...){
  if( pBlob ){
    va_list ap;
    va_start(ap, zFormat);
    vxprintf(pBlob, zFormat, ap);
    va_end(ap);
    pBlob->blobFlags |= BLOBFLAG_NotSQL;
  }
}
void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
  if( pBlob ){
    va_list ap;
    va_start(ap, zFormat);
    vxprintf(pBlob, zFormat, ap);
    va_end(ap);
  }
}
void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){
786
787
788
789
790
791
792


793
794




795
796
797
798
799
800
801

  if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
    nWrote = blob_size(pBlob);
#if defined(_WIN32)
    if( fossil_utf8_to_console(blob_buffer(pBlob), nWrote, 0) >= 0 ){
      return nWrote;
    }


#endif
    fwrite(blob_buffer(pBlob), 1, nWrote, stdout);




  }else{
    file_mkfolder(zFilename, 1);
    out = fossil_fopen(zFilename, "wb");
    if( out==0 ){
      fossil_fatal_recursive("unable to open file \"%s\" for writing",
                             zFilename);
      return 0;







>
>


>
>
>
>







825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846

  if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
    nWrote = blob_size(pBlob);
#if defined(_WIN32)
    if( fossil_utf8_to_console(blob_buffer(pBlob), nWrote, 0) >= 0 ){
      return nWrote;
    }
    fflush(stdout);
    _setmode(_fileno(stdout), _O_BINARY);
#endif
    fwrite(blob_buffer(pBlob), 1, nWrote, stdout);
#if defined(_WIN32)
    fflush(stdout);
    _setmode(_fileno(stdout), _O_TEXT);
#endif
  }else{
    file_mkfolder(zFilename, 1);
    out = fossil_fopen(zFilename, "wb");
    if( out==0 ){
      fossil_fatal_recursive("unable to open file \"%s\" for writing",
                             zFilename);
      return 0;
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168


1169
1170
1171
      }
    }
    /* Make sure the blob contains two terminating 0-bytes */
    blob_append(pBlob, "", 1);
    zUtf8 = blob_str(pBlob) + bomSize;
    zUtf8 = fossil_unicode_to_utf8(zUtf8);
    blob_set_dynamic(pBlob, zUtf8);

#if defined(_WIN32)
  }else if( useMbcs ){
    zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
    blob_reset(pBlob);
    blob_append(pBlob, zUtf8, -1);
    fossil_mbcs_free(zUtf8);


#endif /* _WIN32 */
  }
}







>
|
<




>
>



1201
1202
1203
1204
1205
1206
1207
1208
1209

1210
1211
1212
1213
1214
1215
1216
1217
1218
      }
    }
    /* Make sure the blob contains two terminating 0-bytes */
    blob_append(pBlob, "", 1);
    zUtf8 = blob_str(pBlob) + bomSize;
    zUtf8 = fossil_unicode_to_utf8(zUtf8);
    blob_set_dynamic(pBlob, zUtf8);
  }else if( useMbcs && invalid_utf8(pBlob) ){
#if defined(_WIN32) || defined(__CYGWIN__)

    zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
    blob_reset(pBlob);
    blob_append(pBlob, zUtf8, -1);
    fossil_mbcs_free(zUtf8);
#else
    blob_cp1252_to_utf8(pBlob);
#endif /* _WIN32 */
  }
}
Changes to src/branch.c.
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( colorTest ){
    showClosed = 0;
    showAll = 1;
  }

  style_header(showClosed ? "Closed Branches" :
                  showAll ? "All Branches" : "Open Branches");
  style_submenu_element("Timeline", "Timeline", "brtimeline");
  if( showClosed ){
    style_submenu_element("All", "All", "brlist?all");
    style_submenu_element("Open","Open","brlist");
  }else if( showAll ){
    style_submenu_element("Closed", "Closed", "brlist?closed");
    style_submenu_element("Open","Open","brlist");







|
|







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( colorTest ){
    showClosed = 0;
    showAll = 1;
  }

  style_header("%s", showClosed ? "Closed Branches" :
                        showAll ? "All Branches" : "Open Branches");
  style_submenu_element("Timeline", "Timeline", "brtimeline");
  if( showClosed ){
    style_submenu_element("All", "All", "brlist?all");
    style_submenu_element("Open","Open","brlist");
  }else if( showAll ){
    style_submenu_element("Closed", "Closed", "brlist?closed");
    style_submenu_element("Open","Open","brlist");
Changes to src/browse.c.
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
  if( pManifest==0 ) return 1;
  manifest_file_rewind(pManifest);
  db_prepare(&ins,
     "INSERT INTO temp.fileage(fid, pathname)"
     "  SELECT rid, :path FROM blob WHERE uuid=:uuid"
  );
  while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
    if(zGlob && !strglob(zGlob, pFile->zName)) continue;
    db_bind_text(&ins, ":uuid", pFile->zUuid);
    db_bind_text(&ins, ":path", pFile->zName);
    db_step(&ins);
    db_reset(&ins);
    nFile++;
  }
  db_finalize(&ins);







|







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
  if( pManifest==0 ) return 1;
  manifest_file_rewind(pManifest);
  db_prepare(&ins,
     "INSERT INTO temp.fileage(fid, pathname)"
     "  SELECT rid, :path FROM blob WHERE uuid=:uuid"
  );
  while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
    if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
    db_bind_text(&ins, ":uuid", pFile->zUuid);
    db_bind_text(&ins, ":path", pFile->zName);
    db_step(&ins);
    db_reset(&ins);
    nFile++;
  }
  db_finalize(&ins);
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
  zName = P("name");
  if( zName==0 ) zName = "tip";
  rid = symbolic_name_to_rid(zName, "ci");
  if( rid==0 ){
    fossil_fatal("not a valid check-in: %s", zName);
  }
  style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
  style_header("File Ages", zName);
  zGlob = P("glob");
  compute_fileage(rid,zGlob);
  baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
  zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
  @ <h2>File Ages For Check-in
  @ %z(href("%R/info?name=%T",zName))%h(zName)</a></h2>
  @







|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
  zName = P("name");
  if( zName==0 ) zName = "tip";
  rid = symbolic_name_to_rid(zName, "ci");
  if( rid==0 ){
    fossil_fatal("not a valid check-in: %s", zName);
  }
  style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
  style_header("File Ages");
  zGlob = P("glob");
  compute_fileage(rid,zGlob);
  baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
  zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
  @ <h2>File Ages For Check-in
  @ %z(href("%R/info?name=%T",zName))%h(zName)</a></h2>
  @
Added src/builtin.c.


































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
** Copyright (c) 2014 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)

** 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.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains built-in string and BLOB resources packaged as
** byte arrays.
*/
#include "config.h"
#include "builtin.h"
#include <assert.h>

/*
** The resources provided by this file are packaged by the "mkbuiltin.c"
** utility program during the built process and stored in the
** builtin_data.h file.  Include that information here:
*/
#include "builtin_data.h"

/*
** Return a pointer to built-in content
*/
const unsigned char *builtin_file(const char *zFilename, int *piSize){
  int lwr, upr, i;
  lwr = 0;
  upr = sizeof(aBuiltinFiles)/sizeof(aBuiltinFiles[0]) - 1;
  while( upr>=lwr ){
    i = (upr+lwr)/2;
    if( strcmp(aBuiltinFiles[i].zName,zFilename)==0 ){
      if( piSize ) *piSize = aBuiltinFiles[i].nByte;
      return aBuiltinFiles[i].pData;
    }
  }
  if( piSize ) *piSize = 0;
  return 0;
}

/*
** COMMAND: test-builtin-list
**
** List the names and sizes of all built-in resources
*/
void test_builtin_list(void){
  int i;
  for(i=0; i<sizeof(aBuiltinFiles)/sizeof(aBuiltinFiles[0]); i++){
    fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,aBuiltinFiles[i].nByte);
  }
}

/*
** COMMAND: test-builtin-get
**
** Usage: %fossil test-builtin-get NAME ?OUTPUT-FILE?
*/
void test_builtin_get(void){
  const unsigned char *pData;
  int nByte;
  Blob x;
  if( g.argc!=3 && g.argc!=4 ){
    usage("NAME ?OUTPUT-FILE?");
  }
  pData = builtin_file(g.argv[2], &nByte);
  if( pData==0 ){
    fossil_fatal("no such built-in file: [%s]", g.argv[2]);
  }
  blob_init(&x, (const char*)pData, nByte);
  blob_write_to_file(&x, g.argc==4 ? g.argv[3] : "-");
  blob_reset(&x);
}
Changes to src/cache.c.
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  }
  rc = sqlite3_open(zDbName, &db);
  fossil_free(zDbName);
  if( rc ){
    sqlite3_close(db);
    return 0;
  }
  rc = sqlite3_exec(db, 
     "PRAGMA page_size=8192;"
     "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
     "CREATE TABLE IF NOT EXISTS cache("
       "key TEXT PRIMARY KEY,"     /* Key used to access the cache */
       "id INT REFERENCES blob,"   /* The cache content */
       "sz INT,"                   /* Size of content in bytes */
       "tm INT,"                   /* Last access time (unix timestampe) */







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  }
  rc = sqlite3_open(zDbName, &db);
  fossil_free(zDbName);
  if( rc ){
    sqlite3_close(db);
    return 0;
  }
  rc = sqlite3_exec(db,
     "PRAGMA page_size=8192;"
     "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
     "CREATE TABLE IF NOT EXISTS cache("
       "key TEXT PRIMARY KEY,"     /* Key used to access the cache */
       "id INT REFERENCES blob,"   /* The cache content */
       "sz INT,"                   /* Size of content in bytes */
       "tm INT,"                   /* Last access time (unix timestampe) */
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  int rc;

  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc ){
    sqlite3_finalize(pStmt);
    pStmt = 0;
  }
  return pStmt;  
}

/*
** This routine implements an SQL function that renders a large integer
** compactly:  ex: 12.3MB
*/
static void cache_sizename(







|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  int rc;

  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc ){
    sqlite3_finalize(pStmt);
    pStmt = 0;
  }
  return pStmt;
}

/*
** This routine implements an SQL function that renders a large integer
** compactly:  ex: 12.3MB
*/
static void cache_sizename(
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
  pStmt = cacheStmt(db, "INSERT INTO blob(data) VALUES(?1)");
  if( pStmt==0 ) goto cache_write_end;
  sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
                    SQLITE_STATIC);
  if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
  sqlite3_finalize(pStmt);
  pStmt = cacheStmt(db, 
      "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
      "VALUES(?1,?2,strftime('%s','now'),1,?3)"
  );
  if( pStmt==0 ) goto cache_write_end;
  sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
  sqlite3_bind_int(pStmt, 2, blob_size(pContent));
  sqlite3_bind_int(pStmt, 3, sqlite3_last_insert_rowid(db));







|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
  pStmt = cacheStmt(db, "INSERT INTO blob(data) VALUES(?1)");
  if( pStmt==0 ) goto cache_write_end;
  sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
                    SQLITE_STATIC);
  if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
  sqlite3_finalize(pStmt);
  pStmt = cacheStmt(db,
      "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
      "VALUES(?1,?2,strftime('%s','now'),1,?3)"
  );
  if( pStmt==0 ) goto cache_write_end;
  sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
  sqlite3_bind_int(pStmt, 2, blob_size(pContent));
  sqlite3_bind_int(pStmt, 3, sqlite3_last_insert_rowid(db));
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  sqlite3_stmt *pStmt;
  int rc = 0;

  db = cacheOpen(0);
  if( db==0 ) return 0;
  sqlite3_busy_timeout(db, 10000);
  sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
  pStmt = cacheStmt(db, 
    "SELECT blob.data FROM cache, blob"
    " WHERE cache.key=?1 AND cache.id=blob.id");
  if( pStmt==0 ) goto cache_read_done;
  sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
  if( sqlite3_step(pStmt)==SQLITE_ROW ){
    blob_append(pContent, sqlite3_column_blob(pStmt, 0),
                          sqlite3_column_bytes(pStmt, 0));
    rc = 1;
    sqlite3_reset(pStmt);
    pStmt = cacheStmt(db, 
              "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
              " WHERE key=?1");
    if( pStmt ){
      sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
      sqlite3_step(pStmt);
    }  
  }
  sqlite3_finalize(pStmt);
cache_read_done:
  sqlite3_exec(db, "COMMIT", 0, 0, 0);
  sqlite3_close(db);
  return rc;
}







|









|





|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  sqlite3_stmt *pStmt;
  int rc = 0;

  db = cacheOpen(0);
  if( db==0 ) return 0;
  sqlite3_busy_timeout(db, 10000);
  sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
  pStmt = cacheStmt(db,
    "SELECT blob.data FROM cache, blob"
    " WHERE cache.key=?1 AND cache.id=blob.id");
  if( pStmt==0 ) goto cache_read_done;
  sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
  if( sqlite3_step(pStmt)==SQLITE_ROW ){
    blob_append(pContent, sqlite3_column_blob(pStmt, 0),
                          sqlite3_column_bytes(pStmt, 0));
    rc = 1;
    sqlite3_reset(pStmt);
    pStmt = cacheStmt(db,
              "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
              " WHERE key=?1");
    if( pStmt ){
      sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
      sqlite3_step(pStmt);
    }
  }
  sqlite3_finalize(pStmt);
cache_read_done:
  sqlite3_exec(db, "COMMIT", 0, 0, 0);
  sqlite3_close(db);
  return rc;
}
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
  int nCmd;
  sqlite3 *db;
  sqlite3_stmt *pStmt;

  db_find_and_open_repository(0,0);
  zCmd = g.argc>=3 ? g.argv[2] : "";
  nCmd = (int)strlen(zCmd);
  if( nCmd<=1 ){ 
    fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
  }
  if( strncmp(zCmd, "init", nCmd)==0 ){
    db = cacheOpen(0);
    sqlite3_close(db);
    if( db ){
      fossil_print("cache already exists in file %z\n", cacheName());







|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
  int nCmd;
  sqlite3 *db;
  sqlite3_stmt *pStmt;

  db_find_and_open_repository(0,0);
  zCmd = g.argc>=3 ? g.argv[2] : "";
  nCmd = (int)strlen(zCmd);
  if( nCmd<=1 ){
    fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
  }
  if( strncmp(zCmd, "init", nCmd)==0 ){
    db = cacheOpen(0);
    sqlite3_close(db);
    if( db ){
      fossil_print("cache already exists in file %z\n", cacheName());
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    db = cacheOpen(0);
    if( db==0 ){
      fossil_print("cache does not exist\n");
    }else{
      int nEntry = 0;
      char *zDbName = cacheName();
      cache_register_sizename(db);
      pStmt = cacheStmt(db, 
           "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
           "  FROM cache"
           " ORDER BY tm DESC"
      );
      if( pStmt ){
        while( sqlite3_step(pStmt)==SQLITE_ROW ){
          fossil_print("%s %4d %8s %s\n",







|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    db = cacheOpen(0);
    if( db==0 ){
      fossil_print("cache does not exist\n");
    }else{
      int nEntry = 0;
      char *zDbName = cacheName();
      cache_register_sizename(db);
      pStmt = cacheStmt(db,
           "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
           "  FROM cache"
           " ORDER BY tm DESC"
      );
      if( pStmt ){
        while( sqlite3_step(pStmt)==SQLITE_ROW ){
          fossil_print("%s %4d %8s %s\n",
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  style_header("Web Cache Status");
  db = cacheOpen(0);
  if( db==0 ){
    @ The web-page cache is disabled for this repository
  }else{
    char *zDbName = cacheName();
    cache_register_sizename(db);
    pStmt = cacheStmt(db, 
         "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
         "  FROM cache"
         " ORDER BY tm DESC"
    );
    if( pStmt ){
      @ <ol>
      while( sqlite3_step(pStmt)==SQLITE_ROW ){







|







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  style_header("Web Cache Status");
  db = cacheOpen(0);
  if( db==0 ){
    @ The web-page cache is disabled for this repository
  }else{
    char *zDbName = cacheName();
    cache_register_sizename(db);
    pStmt = cacheStmt(db,
         "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
         "  FROM cache"
         " ORDER BY tm DESC"
    );
    if( pStmt ){
      @ <ol>
      while( sqlite3_step(pStmt)==SQLITE_ROW ){
Changes to src/cgi.c.
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

/*
** Return true if the response should be sent with Content-Encoding: gzip.
*/
static int is_gzippable(void){
  if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
  return strncmp(zContentType, "text/", 5)==0
    || strglob("application/*xml", zContentType)
    || strglob("application/*javascript", zContentType);
}

/*
** Do a normal HTTP reply
*/
void cgi_reply(void){
  int total_size;







|
|







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

/*
** Return true if the response should be sent with Content-Encoding: gzip.
*/
static int is_gzippable(void){
  if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
  return strncmp(zContentType, "text/", 5)==0
    || sqlite3_strglob("application/*xml", zContentType)==0
    || sqlite3_strglob("application/*javascript", zContentType)==0;
}

/*
** Do a normal HTTP reply
*/
void cgi_reply(void){
  int total_size;
1710
1711
1712
1713
1714
1715
1716

1717
1718
1719
1720
1721
1722
1723
1724
  }
  if( iPort>mxPort ) return 1;
  listen(listener,10);
  fossil_print("Listening for %s requests on TCP port %d\n",
     (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP",  iPort);
  fflush(stdout);
  if( zBrowser ){

    zBrowser = mprintf(zBrowser, iPort);
#if defined(__CYGWIN__)
    /* On Cygwin, we can do better than "echo" */
    if( strncmp(zBrowser, "echo ", 5)==0 ){
      wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
      wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
      if( (size_t)ShellExecuteW(0, L"open", wUrl, 0, 0, 1)<33 ){
        fossil_warning("cannot start browser\n");







>
|







1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
  }
  if( iPort>mxPort ) return 1;
  listen(listener,10);
  fossil_print("Listening for %s requests on TCP port %d\n",
     (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP",  iPort);
  fflush(stdout);
  if( zBrowser ){
    assert( strstr(zBrowser,"%d")!=0 );
    zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
#if defined(__CYGWIN__)
    /* On Cygwin, we can do better than "echo" */
    if( strncmp(zBrowser, "echo ", 5)==0 ){
      wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
      wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
      if( (size_t)ShellExecuteW(0, L"open", wUrl, 0, 0, 1)<33 ){
        fossil_warning("cannot start browser\n");
Changes to src/checkin.c.
50
51
52
53
54
55
56

57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    Blob fname;
    file_tree_name(g.argv[i], &fname, 1);
    zName = blob_str(&fname);
    if( fossil_strcmp(zName, ".")==0 ) {
      blob_reset(&where);
      break;
    }

    blob_appendf(&where, " %s (pathname=%Q %s) "
                 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
                 (blob_size(&where)>0) ? "OR" : "AND", zName,
                 filename_collation(), zName, filename_collation(),
                 zName, filename_collation());

  }

  db_prepare(&q,
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE is_selected(id) %s"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
    blob_str(&where)
  );
  blob_zero(&rewrittenPathname);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    const char *zDisplayName = zPathname;
    int isDeleted = db_column_int(&q, 1);
    int isChnged = db_column_int(&q,2);







>
|
|
|
|
|
>







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    Blob fname;
    file_tree_name(g.argv[i], &fname, 1);
    zName = blob_str(&fname);
    if( fossil_strcmp(zName, ".")==0 ) {
      blob_reset(&where);
      break;
    }
    blob_append_sql(&where,
      " %s (pathname=%Q %s) "
      "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
      (blob_size(&where)>0) ? "OR" : "AND", zName,
      filename_collation(), zName, filename_collation(),
      zName, filename_collation()
    );
  }

  db_prepare(&q,
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE is_selected(id) %s"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
    blob_sql_text(&where)
  );
  blob_zero(&rewrittenPathname);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    const char *zDisplayName = zPathname;
    int isDeleted = db_column_int(&q, 1);
    int isChnged = db_column_int(&q,2);
311
312
313
314
315
316
317

318
319
320
321
322

323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340
341
342
343
    Blob fname;
    file_tree_name(g.argv[i], &fname, 1);
    zName = blob_str(&fname);
    if( fossil_strcmp(zName, ".")==0 ) {
      blob_reset(&where);
      break;
    }

    blob_appendf(&where, " %s (pathname=%Q %s) "
                 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
                 (blob_size(&where)>0) ? "OR" : "WHERE", zName,
                 filename_collation(), zName, filename_collation(),
                 zName, filename_collation());

  }
  vfile_check_signature(vid, 0);
  if( showAge ){
    db_prepare(&q,
       "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
       "       datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
       "  FROM vfile %s"
       " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy

    );
  }else{
    db_prepare(&q,
       "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
       "  FROM vfile %s"
       " ORDER BY %s", blob_str(&where), zOrderBy
    );
  }
  blob_reset(&where);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    int isDeleted = db_column_int(&q, 1);
    int isNew = db_column_int(&q,2)==0;







>
|
|
|
|
|
>







|
>





|







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    Blob fname;
    file_tree_name(g.argv[i], &fname, 1);
    zName = blob_str(&fname);
    if( fossil_strcmp(zName, ".")==0 ) {
      blob_reset(&where);
      break;
    }
    blob_append_sql(&where,
       " %s (pathname=%Q %s) "
       "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
       (blob_size(&where)>0) ? "OR" : "WHERE", zName,
       filename_collation(), zName, filename_collation(),
       zName, filename_collation()
    );
  }
  vfile_check_signature(vid, 0);
  if( showAge ){
    db_prepare(&q,
       "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
       "       datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
       "  FROM vfile %s"
       " ORDER BY %s",
       vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/
    );
  }else{
    db_prepare(&q,
       "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
       "  FROM vfile %s"
       " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
    );
  }
  blob_reset(&where);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    int isDeleted = db_column_int(&q, 1);
    int isNew = db_column_int(&q,2)==0;
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
int select_commit_files(void){
  int result = 0;
  assert( g.aCommitFile==0 );
  if( g.argc>2 ){
    int ii, jj=0;
    Blob fname;
    Stmt q;
    const char *zCollate;
    Bag toCommit;

    zCollate = filename_collation();
    blob_zero(&fname);
    bag_init(&toCommit);
    for(ii=2; ii<g.argc; ii++){
      int cnt = 0;
      file_tree_name(g.argv[ii], &fname, 1);
      if( fossil_strcmp(blob_str(&fname),".")==0 ){
        bag_clear(&toCommit);
        return result;
      }
      db_prepare(&q,
        "SELECT id FROM vfile WHERE pathname=%Q %s"
        " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
        blob_str(&fname), zCollate, blob_str(&fname),
        zCollate, blob_str(&fname), zCollate);
      while( db_step(&q)==SQLITE_ROW ){
        cnt++;
        bag_insert(&toCommit, db_column_int(&q, 0));
      }
      db_finalize(&q);
      if( cnt==0 ){
        fossil_warning("fossil knows nothing about: %s", g.argv[ii]);







<


<












|
|







911
912
913
914
915
916
917

918
919

920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
int select_commit_files(void){
  int result = 0;
  assert( g.aCommitFile==0 );
  if( g.argc>2 ){
    int ii, jj=0;
    Blob fname;
    Stmt q;

    Bag toCommit;


    blob_zero(&fname);
    bag_init(&toCommit);
    for(ii=2; ii<g.argc; ii++){
      int cnt = 0;
      file_tree_name(g.argv[ii], &fname, 1);
      if( fossil_strcmp(blob_str(&fname),".")==0 ){
        bag_clear(&toCommit);
        return result;
      }
      db_prepare(&q,
        "SELECT id FROM vfile WHERE pathname=%Q %s"
        " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
        blob_str(&fname), filename_collation(), blob_str(&fname),
        filename_collation(), blob_str(&fname), filename_collation());
      while( db_step(&q)==SQLITE_ROW ){
        cnt++;
        bag_insert(&toCommit, db_column_int(&q, 0));
      }
      db_finalize(&q);
      if( cnt==0 ){
        fossil_warning("fossil knows nothing about: %s", g.argv[ii]);
Changes to src/checkout.c.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
*/
int load_vfile(const char *zName, int forceMissingFlag){
  Blob uuid;
  int vid;

  blob_init(&uuid, zName, -1);
  if( name_to_uuid(&uuid, 1, "ci") ){
    fossil_fatal(g.zErrMsg);
  }
  vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
  if( vid==0 ){
    fossil_fatal("no such check-in: %s", g.argv[2]);
  }
  if( !is_a_version(vid) ){
    fossil_fatal("object [%S] is not a check-in", blob_str(&uuid));







|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
*/
int load_vfile(const char *zName, int forceMissingFlag){
  Blob uuid;
  int vid;

  blob_init(&uuid, zName, -1);
  if( name_to_uuid(&uuid, 1, "ci") ){
    fossil_fatal("%s", g.zErrMsg);
  }
  vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
  if( vid==0 ){
    fossil_fatal("no such check-in: %s", g.argv[2]);
  }
  if( !is_a_version(vid) ){
    fossil_fatal("object [%S] is not a check-in", blob_str(&uuid));
Added src/codecheck1.c.






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
/*
** Copyright (c) 2014 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** 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.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This program reads Fossil source code files and tries to verify that
** printf-style format strings are correct.
**
** This program implements a compile-time validation step on the Fossil
** source code.  Running this program is entirely optional.  Its role is
** similar to the -Wall compiler switch on gcc, or the scan-build utility
** of clang, or other static analyzers.  The purpose is to try to identify
** problems in the source code at compile-time.  The difference is that this
** static checker is specifically designed for the particular printf formatter
** implementation used by Fossil.
**
** Checks include:
**
**    *  Verify that vararg formatting routines like blob_printf() or
**       db_multi_exec() have the correct number of arguments for their
**       format string.
**
**    *  For routines designed to generate SQL, warn about the use of %s
**       which might allow SQL injection.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>

/*
** Malloc, aborting if it fails.
*/
void *safe_malloc(int nByte){
  void *x = malloc(nByte);
  if( x==0 ){
    fprintf(stderr, "failed to allocate %d bytes\n", nByte);
    exit(1);
  }
  return x;
}
void *safe_realloc(void *pOld, int nByte){
  void *x = realloc(pOld, nByte);
  if( x==0 ){
    fprintf(stderr, "failed to allocate %d bytes\n", nByte);
    exit(1);
  }
  return x;
}

/*
** Read the entire content of the file named zFilename into memory obtained
** from malloc().   Add a zero-terminator to the end.
** Return a pointer to that memory.
*/
static char *read_file(const char *zFilename){
  FILE *in;
  char *z;
  int nByte;
  int got;
  in = fopen(zFilename, "rb");
  if( in==0 ){
    return 0;
  }
  fseek(in, 0, SEEK_END);
  nByte = ftell(in);
  fseek(in, 0, SEEK_SET);
  z = safe_malloc( nByte+1 );
  got = fread(z, 1, nByte, in);
  z[got] = 0;
  fclose(in);
  return z;
}

/*
** When parsing the input file, the following token types are recognized.
*/
#define TK_SPACE      1      /* Whitespace or comments */
#define TK_ID         2      /* An identifier */
#define TK_STR        3      /* A string literal in double-quotes */
#define TK_OTHER      4      /* Any other token */
#define TK_EOF       99      /* End of file */

/*
** Determine the length and type of the token beginning at z[0]
*/
static int token_length(const char *z, int *pType, int *pLN){
  int i;
  if( z[0]==0 ){
    *pType = TK_EOF;
    return 0;
  }
  if( z[0]=='"' || z[0]=='\'' ){
    for(i=1; z[i] && z[i]!=z[0]; i++){
      if( z[i]=='\\' && z[i+1]!=0 ){
        if( z[i+1]=='\n' ) (*pLN)++;
        i++;
      }
    }
    if( z[i]!=0 ) i++;
    *pType = z[0]=='"' ? TK_STR : TK_OTHER;
    return i;
  }
  if( isalnum(z[0]) || z[0]=='_' ){
    for(i=1; isalnum(z[i]) || z[i]=='_'; i++){}
    *pType = isalpha(z[0]) || z[0]=='_' ? TK_ID : TK_OTHER;
    return i;
  }
  if( isspace(z[0]) ){
    if( z[0]=='\n' ) (*pLN)++;
    for(i=1; isspace(z[i]); i++){
      if( z[i]=='\n' ) (*pLN)++;
    }
    *pType = TK_SPACE;
    return i;
  }
  if( z[0]=='/' && z[1]=='*' ){
    for(i=2; z[i] && (z[i]!='*' || z[i+1]!='/'); i++){
      if( z[i]=='\n' ) (*pLN)++;
    }
    if( z[i] ) i += 2;
    *pType = TK_SPACE;
    return i;
  }
  if( z[0]=='/' && z[1]=='/' ){
    for(i=2; z[i] && z[i]!='\n'; i++){}
    if( z[i] ){
      (*pLN)++;
      i++;
    }
    *pType = TK_SPACE;
    return i;
  }
  *pType = TK_OTHER;
  return 1;
}

/*
** Return the next non-whitespace token
*/
const char *next_non_whitespace(const char *z, int *pLen, int *pType){
  int len;
  int eType;
  int ln = 0;
  while( (len = token_length(z, &eType, &ln))>0 && eType==TK_SPACE ){
    z += len;
  }
  *pLen = len;
  *pType = eType;
  return z;
}

/*
** Return index into z[] for the first balanced TK_OTHER token with
** value cValue.
*/
static int distance_to(const char *z, char cVal){
  int len;
  int dist = 0;
  int eType;
  int nNest = 0;
  int ln = 0;
  while( z[0] && (len = token_length(z, &eType, &ln))>0 ){
    if( eType==TK_OTHER ){
      if( z[0]==cVal && nNest==0 ){
        break;
      }else if( z[0]=='(' ){
        nNest++;
      }else if( z[0]==')' ){
        nNest--;
      }
    }
    dist += len;
    z += len;
  }
  return dist;
}

/*
** Return the first non-whitespace characters in z[]
*/
static const char *skip_space(const char *z){
  while( isspace(z[0]) ){ z++; }
  return z;
}

/*
** Return true if the input is a string literal.
*/
static int is_string_lit(const char *z){
  int nu1, nu2;
  z = next_non_whitespace(z, &nu1, &nu2);
  return z[0]=='"';
}

/*
** Return true if the input is an expression of string literals:
**
**      EXPR ? "..." : "..."
*/
static int is_string_expr(const char *z){
  int len = 0, eType;
  const char *zOrig = z;
  len = distance_to(z, '?');
  if( z[len]==0 && skip_space(z)[0]=='(' ){
    z = skip_space(z) + 1;
    len = distance_to(z, '?');
  }
  z += len;
  if( z[0]=='?' ){
    z++;
    z = next_non_whitespace(z, &len, &eType);
    if( eType==TK_STR ){
      z += len;
      z = next_non_whitespace(z, &len, &eType);
      if( eType==TK_OTHER && z[0]==':' ){
        z += len;
        z = next_non_whitespace(z, &len, &eType);
        if( eType==TK_STR ){
          z += len;
          z = next_non_whitespace(z, &len, &eType);
          if( eType==TK_EOF ) return 1;
          if( eType==TK_OTHER && z[0]==')' && skip_space(zOrig)[0]=='(' ){
            z += len;
            z = next_non_whitespace(z, &len, &eType);
            if( eType==TK_EOF ) return 1;
          }
        }
      }
    }
  }
  return 0;
}

/*
** A list of functions that return strings that are safe to insert into
** SQL using %s.
*/
static const char *azSafeFunc[] = {
  "filename_collation",
  "db_name",
  "timeline_utc",
  "leaf_is_closed_sql",
  "timeline_query_for_www",
  "timeline_query_for_tty",
  "blob_sql_text",
  "glob_expr",
  "fossil_all_reserved_names",
  "configure_inop_rhs",
  "db_setting_inop_rhs",
};

/*
** Return true if the input is an argument that is safe to use with %s
** while building an SQL statement.
*/
static int is_s_safe(const char *z){
  int len, eType;
  int i;

  /* A string literal is safe for use with %s */
  if( is_string_lit(z) ) return 1;

  /* Certain functions are guaranteed to return a string that is safe
  ** for use with %s */
  z = next_non_whitespace(z, &len, &eType);
  for(i=0; i<sizeof(azSafeFunc)/sizeof(azSafeFunc[0]); i++){
    if( eType==TK_ID 
     && strncmp(z, azSafeFunc[i], len)==0
     && strlen(azSafeFunc[i])==len
    ){
      return 1;
    }
  }

  /* Expressions of the form:  EXPR ? "..." : "...." can count as
  ** a string literal. */
  if( is_string_expr(z) ) return 1;

  /* If the "safe-for-%s" comment appears in the argument, then
  ** let it through */
  if( strstr(z, "/*safe-for-%s*/")!=0 ) return 1;
    
  return 0;
}

/*
** Processing flags
*/
#define FMT_NO_S   0x00001     /* Do not allow %s substitutions */

/*
** A list of internal Fossil interfaces that take a printf-style format
** string.
*/
struct {
  const char *zFName;    /* Name of the function */
  int iFmtArg;           /* Index of format argument.  Leftmost is 1. */
  unsigned fmtFlags;     /* Processing flags */
} aFmtFunc[] = {
  { "blob_append_sql",         2, FMT_NO_S },
  { "blob_appendf",            2, 0 },
  { "cgi_panic",               1, 0 },
  { "cgi_redirectf",           1, 0 },
  { "db_blob",                 2, FMT_NO_S },
  { "db_double",               2, FMT_NO_S },
  { "db_err",                  1, 0 },
  { "db_exists",               1, FMT_NO_S },
  { "db_int",                  2, FMT_NO_S },
  { "db_int64",                2, FMT_NO_S },
  { "db_multi_exec",           1, FMT_NO_S },
  { "db_optional_sql",         2, FMT_NO_S },
  { "db_prepare",              2, FMT_NO_S },
  { "db_prepare_ignore_error", 2, FMT_NO_S },
  { "db_static_prepare",       2, FMT_NO_S },
  { "db_text",                 2, FMT_NO_S },
  { "form_begin",              2, 0 },
  { "fossil_error",            2, 0 },
  { "fossil_errorlog",         1, 0 },
  { "fossil_fatal",            1, 0 },
  { "fossil_fatal_recursive",  1, 0 },
  { "fossil_panic",            1, 0 },
  { "fossil_print",            1, 0 },
  { "fossil_trace",            1, 0 },
  { "fossil_warning",          1, 0 },
  { "href",                    1, 0 },
  { "json_new_string_f",       1, 0 },
  { "mprintf",                 1, 0 },
  { "socket_set_errmsg",       1, 0 },
  { "ssl_set_errmsg",          1, 0 },
  { "style_header",            1, 0 },
  { "style_set_current_page",  1, 0 },
  { "webpage_error",           1, 0 },
  { "xhref",                   2, 0 },
};

/*
** Determine if the indentifier zIdent of length nIndent is a Fossil
** internal interface that uses a printf-style argument.  Return zero if not.
** Return the index of the format string if true with the left-most
** argument having an index of 1.
*/
static int isFormatFunc(const char *zIdent, int nIdent, unsigned *pFlags){
  int upr, lwr;
  lwr = 0;
  upr = sizeof(aFmtFunc)/sizeof(aFmtFunc[0]) - 1;
  while( lwr<=upr ){
    unsigned x = (lwr + upr)/2;
    int c = strncmp(zIdent, aFmtFunc[x].zFName, nIdent);
    if( c==0 ){
      if( aFmtFunc[x].zFName[nIdent]==0 ){
        *pFlags = aFmtFunc[x].fmtFlags;
        return aFmtFunc[x].iFmtArg;
      }
      c = -1;
    }
    if( c<0 ){
      upr = x - 1;
    }else{
      lwr = x + 1;
    }
  }
  *pFlags = 0;
  return 0;
}

/*
** Return the expected number of arguments for the format string.
** Return -1 if the value cannot be computed.
**
** For each argument less than nType, store the conversion character
** for that argument in cType[i].
*/
static int formatArgCount(const char *z, int nType, char *cType){
  int nArg = 0;
  int i, k;
  int len;
  int eType;
  int ln = 0;
  while( z[0] ){
    len = token_length(z, &eType, &ln);
    if( eType==TK_STR ){
      for(i=1; i<len-1; i++){
        if( z[i]!='%' ) continue;
        if( z[i+1]=='%' ){ i++; continue; }
        for(k=i+1; k<len && !isalpha(z[k]); k++){
          if( z[k]=='*' || z[k]=='#' ){
            if( nArg<nType ) cType[nArg] = z[k];
            nArg++;
          }
        }
        if( z[k]!='R' ){
          if( nArg<nType ) cType[nArg] = z[k];
          nArg++;
        }
      }
    }
    z += len;
  }
  return nArg;
}

/*
** The function call that begins at zFCall[0] (which is on line lnFCall of the
** original file) is a function that uses a printf-style format string
** on argument number fmtArg.  It has processings flags fmtFlags.  Do
** compile-time checking on this function, output any errors, and return
** the number of errors.
*/
static int checkFormatFunc(
  const char *zFilename, /* Name of the file being processed */
  const char *zFCall,    /* Pointer to start of function call */
  int lnFCall,           /* Line number that holds z[0] */
  int fmtArg,            /* Format string should be this argument */
  int fmtFlags           /* Extra processing flags */
){
  int szFName;
  int eToken;
  int ln = lnFCall;
  int len;
  const char *zStart;
  char *z;
  char *zCopy;
  int nArg = 0;
  const char **azArg = 0;
  int i, k;
  int nErr = 0;
  char *acType;

  szFName = 	token_length(zFCall, &eToken, &ln);
  zStart = next_non_whitespace(zFCall+szFName, &len, &eToken);
  assert( zStart[0]=='(' && len==1 );
  len = distance_to(zStart+1, ')');
  zCopy = safe_malloc( len + 1 );
  memcpy(zCopy, zStart+1, len);
  zCopy[len] = 0;
  azArg = 0;
  nArg = 0;
  z = zCopy;
  while( z[0] ){
    len = distance_to(z, ',');
    azArg = safe_realloc((char*)azArg, (sizeof(azArg[0])+1)*(nArg+1));
    azArg[nArg++] = skip_space(z);
    if( z[len]==0 ) break;
    z[len] = 0;
    for(i=len-1; i>0 && isspace(z[i]); i--){ z[i] = 0; }
    z += len + 1;
  }
  acType = (char*)&azArg[nArg];
  if( fmtArg>nArg ){
    printf("%s:%d: too few arguments to %.*s()\n", 
           zFilename, lnFCall, szFName, zFCall);
    nErr++;
  }else{
    const char *zFmt = azArg[fmtArg-1];
    const char *zOverride = strstr(zFmt, "/*works-like:");
    if( zOverride ) zFmt = zOverride + sizeof("/*works-like:")-1;
    if( !is_string_lit(zFmt) ){
      printf("%s:%d: %.*s() has non-constant format string\n",
             zFilename, lnFCall, szFName, zFCall);
      nErr++;
    }else if( (k = formatArgCount(zFmt, nArg, acType))>=0
             && nArg!=fmtArg+k ){
      printf("%s:%d: too %s arguments to %.*s() "
             "- got %d and expected %d\n",
             zFilename, lnFCall, (nArg<fmtArg+k ? "few" : "many"),
             szFName, zFCall, nArg, fmtArg+k);
      nErr++;
    }else if( fmtFlags & FMT_NO_S ){
      for(i=0; i<nArg && i<k; i++){
        if( (acType[i]=='s' || acType[i]=='z' || acType[i]=='b')
         && !is_s_safe(azArg[fmtArg+i])
        ){
           printf("%s:%d: Argument %d to %.*s() not safe for SQL\n",
             zFilename, lnFCall, i+fmtArg, szFName, zFCall);
           nErr++;
        }
      }
    }
  }
  if( nErr ){
    for(i=0; i<nArg; i++){
      printf("   arg[%d]: %s\n", i, azArg[i]);
    }
  }

  free((char*)azArg);
  free(zCopy);
  return nErr;
}


/*
** Do a design-rule check of format strings for the file named zName
** with content zContent.  Write errors on standard output.  Return
** the number of errors.
*/
static int scan_file(const char *zName, const char *zContent){
  const char *z;
  int ln = 0;
  int szToken;
  int eToken;
  const char *zPrev;
  int ePrev;
  int szPrev;
  int lnPrev;
  int nCurly = 0;
  int x;
  unsigned fmtFlags = 0;
  int nErr = 0;

  if( zContent==0 ){
    printf("cannot read file: %s\n", zName);
    return 1;
  }
  for(z=zContent; z[0]; z += szToken){
    szToken = token_length(z, &eToken, &ln);
    if( eToken==TK_SPACE ) continue;
    if( eToken==TK_OTHER ){
      if( z[0]=='{' ){
        nCurly++;
      }else if( z[0]=='}' ){
        nCurly--;
      }else if( nCurly>0 && z[0]=='(' && ePrev==TK_ID
            && (x = isFormatFunc(zPrev,szPrev,&fmtFlags))>0 ){
        nErr += checkFormatFunc(zName, zPrev, lnPrev, x, fmtFlags);
      }
    }    
    zPrev = z;
    ePrev = eToken;
    szPrev = szToken;
    lnPrev = ln;
  }
  return nErr;
}

/*
** Check for format-string design rule violations on all files listed
** on the command-line.
*/
int main(int argc, char **argv){
  int i;
  int nErr = 0;
  for(i=1; i<argc; i++){
    char *zFile = read_file(argv[i]);
    nErr += scan_file(argv[i], zFile);
    free(zFile);
  }
  return nErr;
}
Changes to src/comformat.c.
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
    if( zOrigText ){
      blob_read_from_file(&fileData, zOrigText);
      zOrigText = mprintf("%s", blob_str(&fileData));
      blob_reset(&fileData);
    }
  }
  if( decode ){
    zText = mprintf(fromFile ? "%z" : "%s", zText);
    defossilize(zText);
    if( zOrigText ){
      zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText);
      defossilize(zOrigText);
    }
  }
  if( indent<0 ){
    indent = strlen(zPrefix);
  }
  if( zPrefix && *zPrefix ){







|


|







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
    if( zOrigText ){
      blob_read_from_file(&fileData, zOrigText);
      zOrigText = mprintf("%s", blob_str(&fileData));
      blob_reset(&fileData);
    }
  }
  if( decode ){
    zText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zText);
    defossilize(zText);
    if( zOrigText ){
      zOrigText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zOrigText);
      defossilize(zOrigText);
    }
  }
  if( indent<0 ){
    indent = strlen(zPrefix);
  }
  if( zPrefix && *zPrefix ){
Changes to src/configure.c.
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
*/
const char *configure_inop_rhs(int iMask){
  Blob x;
  int i;
  const char *zSep = "";

  blob_zero(&x);
  blob_append(&x, "(", 1);
  for(i=0; i<count(aConfig); i++){
    if( (aConfig[i].groupMask & iMask)==0 ) continue;
    if( aConfig[i].zName[0]=='@' ) continue;
    blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName);
    zSep = ",";
  }
  blob_append(&x, ")", 1);
  return blob_str(&x);
}

/*
** Return the mask for the named configuration parameter if it can be
** safely exported.  Return 0 if the parameter is not safe to export.
**
** "Safe" in the previous paragraph means the permission is created to







|



|


|
|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
*/
const char *configure_inop_rhs(int iMask){
  Blob x;
  int i;
  const char *zSep = "";

  blob_zero(&x);
  blob_append_sql(&x, "(");
  for(i=0; i<count(aConfig); i++){
    if( (aConfig[i].groupMask & iMask)==0 ) continue;
    if( aConfig[i].zName[0]=='@' ) continue;
    blob_append_sql(&x, "%s'%q'", zSep/*safe-for-%s*/, aConfig[i].zName);
    zSep = ",";
  }
  blob_append_sql(&x, ")");
  return blob_sql_text(&x);
}

/*
** Return the mask for the named configuration parameter if it can be
** safely exported.  Return 0 if the parameter is not safe to export.
**
** "Safe" in the previous paragraph means the permission is created to
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
    @   photo BLOB                      -- JPEG image of this user
    @ );
    @ INSERT INTO _xfer_reportfmt
    @    SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
    @ INSERT INTO _xfer_user
    @    SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
  ;

  db_multi_exec(zSQL1);

  /* When the replace flag is set, add triggers that run the first time
  ** that new data is seen.  The triggers run only once and delete all the
  ** existing data.
  */
  if( replaceFlag ){
    static const char zSQL2[] =







>
|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
    @   photo BLOB                      -- JPEG image of this user
    @ );
    @ INSERT INTO _xfer_reportfmt
    @    SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
    @ INSERT INTO _xfer_user
    @    SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
  ;
  assert( strchr(zSQL1,'%')==0 );
  db_multi_exec(zSQL1 /*works-like:""*/);

  /* When the replace flag is set, add triggers that run the first time
  ** that new data is seen.  The triggers run only once and delete all the
  ** existing data.
  */
  if( replaceFlag ){
    static const char zSQL2[] =
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419
      @ END;
    ;
    sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
         config_is_reset_function, 0, 0);
    sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
         config_reset_function, 0, 0);
    configHasBeenReset = 0;

    db_multi_exec(zSQL2);
  }
}

/*
** After receiving configuration data, call this routine to transfer
** the results into the main database.
*/
void configure_finalize_receive(void){
  static const char zSQL[] =
    @ DELETE FROM user;
    @ INSERT INTO user SELECT * FROM _xfer_user;
    @ DELETE FROM reportfmt;
    @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
    @ DROP TABLE _xfer_user;
    @ DROP TABLE _xfer_reportfmt;
  ;

  db_multi_exec(zSQL);
}

/*
** Mask of modified configuration sets
*/
static int rebuildMask = 0;








>
|
















>
|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
      @ END;
    ;
    sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
         config_is_reset_function, 0, 0);
    sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
         config_reset_function, 0, 0);
    configHasBeenReset = 0;
    assert( strchr(zSQL2,'%')==0 );
    db_multi_exec(zSQL2 /*works-like:""*/);
  }
}

/*
** After receiving configuration data, call this routine to transfer
** the results into the main database.
*/
void configure_finalize_receive(void){
  static const char zSQL[] =
    @ DELETE FROM user;
    @ INSERT INTO user SELECT * FROM _xfer_user;
    @ DELETE FROM reportfmt;
    @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
    @ DROP TABLE _xfer_user;
    @ DROP TABLE _xfer_reportfmt;
  ;
  assert( strchr(zSQL,'%')==0 );
  db_multi_exec(zSQL /*works-like:""*/);
}

/*
** Mask of modified configuration sets
*/
static int rebuildMask = 0;

561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585

586
587

588
589
590
591

592
593
594
595
596
597
598
599
      thisMask = configure_is_exportable(aType[ii].zName);
    }
    if( (thisMask & groupMask)==0 ) return;

    blob_zero(&sql);
    if( groupMask & CONFIGSET_OVERWRITE ){
      if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
        db_multi_exec("DELETE FROM %s", &aType[ii].zName[1]);
        configHasBeenReset |= thisMask;
      }
      blob_append(&sql, "REPLACE INTO ", -1);
    }else{
      blob_append(&sql, "INSERT OR IGNORE INTO ", -1);
    }
    blob_appendf(&sql, "%s(%s, mtime", &zName[1], aType[ii].zPrimKey);
    for(jj=2; jj<nToken; jj+=2){
       blob_appendf(&sql, ",%s", azToken[jj]);
    }
    blob_appendf(&sql,") VALUES(%s,%s", azToken[1], azToken[0]);

    for(jj=2; jj<nToken; jj+=2){
       blob_appendf(&sql, ",%s", azToken[jj+1]);
    }
    db_multi_exec("%s)", blob_str(&sql));
    if( db_changes()==0 ){
      blob_reset(&sql);

      blob_appendf(&sql, "UPDATE %s SET mtime=%s", &zName[1], azToken[0]);
      for(jj=2; jj<nToken; jj+=2){

        blob_appendf(&sql, ", %s=%s", azToken[jj], azToken[jj+1]);
      }
      blob_appendf(&sql, " WHERE %s=%s AND mtime<%s",
                   aType[ii].zPrimKey, azToken[1], azToken[0]);

      db_multi_exec("%s", blob_str(&sql));
    }
    blob_reset(&sql);
    rebuildMask |= thisMask;
  }else{
    /* Otherwise, the old format */
    if( (configure_is_exportable(zName) & groupMask)==0 ) return;
    if( fossil_strcmp(zName, "logo-image")==0 ){







|


|

|

|

|

|
>

|

|


>
|

>
|

|
|
>
|







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
      thisMask = configure_is_exportable(aType[ii].zName);
    }
    if( (thisMask & groupMask)==0 ) return;

    blob_zero(&sql);
    if( groupMask & CONFIGSET_OVERWRITE ){
      if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
        db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
        configHasBeenReset |= thisMask;
      }
      blob_append_sql(&sql, "REPLACE INTO ");
    }else{
      blob_append_sql(&sql, "INSERT OR IGNORE INTO ");
    }
    blob_append_sql(&sql, "\"%w\"(\"%w\", mtime", &zName[1], aType[ii].zPrimKey);
    for(jj=2; jj<nToken; jj+=2){
       blob_append_sql(&sql, ",\"%w\"", azToken[jj]);
    }
    blob_append_sql(&sql,") VALUES(%s,%s",
       azToken[1] /*safe-for-%s*/, azToken[0] /*safe-for-%s*/);
    for(jj=2; jj<nToken; jj+=2){
       blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/);
    }
    db_multi_exec("%s)", blob_sql_text(&sql));
    if( db_changes()==0 ){
      blob_reset(&sql);
      blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s",
                      &zName[1], azToken[0]/*safe-for-%s*/);
      for(jj=2; jj<nToken; jj+=2){
        blob_append_sql(&sql, ", \"%w\"=%s",
                        azToken[jj], azToken[jj+1]/*safe-for-%s*/);
      }
      blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s",
                   aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/,
                   azToken[0]/*safe-for-%s*/);
      db_multi_exec("%s", blob_sql_text(&sql));
    }
    blob_reset(&sql);
    rebuildMask |= thisMask;
  }else{
    /* Otherwise, the old format */
    if( (configure_is_exportable(zName) & groupMask)==0 ) return;
    if( fossil_strcmp(zName, "logo-image")==0 ){
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
      db_finalize(&ins);
    }else if( zName[0]=='@' ){
      /* Notice that we are evaluating arbitrary SQL received from the
      ** client.  But this can only happen if the client has authenticated
      ** as an administrator, so presumably we trust the client at this
      ** point.
      */
      db_multi_exec("%s", blob_str(pContent));
    }else{
      db_multi_exec(
         "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
         zName, blob_str(pContent)
      );
    }
  }







|







614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
      db_finalize(&ins);
    }else if( zName[0]=='@' ){
      /* Notice that we are evaluating arbitrary SQL received from the
      ** client.  But this can only happen if the client has authenticated
      ** as an administrator, so presumably we trust the client at this
      ** point.
      */
      db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/);
    }else{
      db_multi_exec(
         "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
         zName, blob_str(pContent)
      );
    }
  }
964
965
966
967
968
969
970

971
972
973
974
975
976
977
978
        db_create_default_users(0, 0);
      }else if( fossil_strcmp(zName,"@concealed")==0 ){
        db_multi_exec("DELETE FROM concealed");
      }else if( fossil_strcmp(zName,"@shun")==0 ){
        db_multi_exec("DELETE FROM shun");
      }else if( fossil_strcmp(zName,"@reportfmt")==0 ){
        db_multi_exec("DELETE FROM reportfmt");

        db_multi_exec(zRepositorySchemaDefaultReports);
      }
    }
    db_end_transaction(0);
    fossil_print("Configuration reset to factory defaults.\n");
    fossil_print("To recover, use:  %s %s import %s\n",
            g.argv[0], g.argv[1], zBackup);
    rebuildMask |= mask;







>
|







971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
        db_create_default_users(0, 0);
      }else if( fossil_strcmp(zName,"@concealed")==0 ){
        db_multi_exec("DELETE FROM concealed");
      }else if( fossil_strcmp(zName,"@shun")==0 ){
        db_multi_exec("DELETE FROM shun");
      }else if( fossil_strcmp(zName,"@reportfmt")==0 ){
        db_multi_exec("DELETE FROM reportfmt");
        assert( strchr(zRepositorySchemaDefaultReports,'%')==0 );
        db_multi_exec(zRepositorySchemaDefaultReports /*works-like:""*/);
      }
    }
    db_end_transaction(0);
    fossil_print("Configuration reset to factory defaults.\n");
    fossil_print("To recover, use:  %s %s import %s\n",
            g.argv[0], g.argv[1], zBackup);
    rebuildMask |= mask;
Changes to src/content.c.
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
      isDephantomize = 1;
      content_mark_available(rid);
    }
  }else{
    /* We are creating a new entry */
    db_prepare(&s1,
      "INSERT INTO blob(rcvid,size,uuid,content)"
      "VALUES(%d,%d,'%b',:data)",
       g.rcvid, size, &hash
    );
    db_bind_blob(&s1, ":data", &cmpr);
    db_exec(&s1);
    rid = db_last_insert_rowid();
    if( !pBlob ){
      db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid);
    }







|
|







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
      isDephantomize = 1;
      content_mark_available(rid);
    }
  }else{
    /* We are creating a new entry */
    db_prepare(&s1,
      "INSERT INTO blob(rcvid,size,uuid,content)"
      "VALUES(%d,%d,'%q',:data)",
       g.rcvid, size, blob_str(&hash)
    );
    db_bind_blob(&s1, ":data", &cmpr);
    db_exec(&s1);
    rid = db_last_insert_rowid();
    if( !pBlob ){
      db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid);
    }
Changes to src/db.c.
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    }
    for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){
      db.doRollback |= db.aHook[i].xHook();
    }
    while( db.pAllStmt ){
      db_finalize(db.pAllStmt);
    }
    db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
    db.doRollback = 0;
  }
}

/*
** Force a rollback and shutdown the database
*/







|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    }
    for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){
      db.doRollback |= db.aHook[i].xHook();
    }
    while( db.pAllStmt ){
      db_finalize(db.pAllStmt);
    }
    db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
    db.doRollback = 0;
  }
}

/*
** Force a rollback and shutdown the database
*/
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  const char *zSql;
  va_list ap;

  db = db_open(zFileName);
  sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
  rc = sqlite3_exec(db, zSchema, 0, 0, 0);
  if( rc!=SQLITE_OK ){
    db_err(sqlite3_errmsg(db));
  }
  va_start(ap, zSchema);
  while( (zSql = va_arg(ap, const char*))!=0 ){
    rc = sqlite3_exec(db, zSql, 0, 0, 0);
    if( rc!=SQLITE_OK ){
      db_err(sqlite3_errmsg(db));
    }
  }
  va_end(ap);
  sqlite3_exec(db, "COMMIT", 0, 0, 0);
  sqlite3_close(db);
}








|





|







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  const char *zSql;
  va_list ap;

  db = db_open(zFileName);
  sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
  rc = sqlite3_exec(db, zSchema, 0, 0, 0);
  if( rc!=SQLITE_OK ){
    db_err("%s", sqlite3_errmsg(db));
  }
  va_start(ap, zSchema);
  while( (zSql = va_arg(ap, const char*))!=0 ){
    rc = sqlite3_exec(db, zSql, 0, 0, 0);
    if( rc!=SQLITE_OK ){
      db_err("%s", sqlite3_errmsg(db));
    }
  }
  va_end(ap);
  sqlite3_exec(db, "COMMIT", 0, 0, 0);
  sqlite3_close(db);
}

751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
}


/*
** Detaches the zLabel database.
*/
void db_detach(const char *zLabel){
  db_multi_exec("DETACH DATABASE %s", zLabel);
}

/*
** zDbName is the name of a database file.  Attach zDbName using
** the name zLabel.
*/
void db_attach(const char *zDbName, const char *zLabel){
  db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
}

/*
** zDbName is the name of a database file.  If no other database
** file is open, then open this one.  If another database file is
** already open, then attach zDbName using the name zLabel.
*/







|







|







751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
}


/*
** Detaches the zLabel database.
*/
void db_detach(const char *zLabel){
  db_multi_exec("DETACH DATABASE %Q", zLabel);
}

/*
** zDbName is the name of a database file.  Attach zDbName using
** the name zLabel.
*/
void db_attach(const char *zDbName, const char *zLabel){
  db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
}

/*
** zDbName is the name of a database file.  If no other database
** file is open, then open this one.  If another database file is
** already open, then attach zDbName using the name zLabel.
*/
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
** zColumn
*/
static int db_local_table_exists_but_lacks_column(
  const char *zTable,
  const char *zColumn
){
  char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
                   " WHERE name=='%s' /*scan*/",
                   db_name("localdb"), zTable);
  int rc = 0;
  if( zDef ){
    char *zPattern = mprintf("* %s *", zColumn);
    rc = strglob(zPattern, zDef)==0;
    fossil_free(zPattern);
    fossil_free(zDef);
  }
  return rc;
}

/*







|




|







888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
** zColumn
*/
static int db_local_table_exists_but_lacks_column(
  const char *zTable,
  const char *zColumn
){
  char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
                   " WHERE name==%Q /*scan*/",
                   db_name("localdb"), zTable);
  int rc = 0;
  if( zDef ){
    char *zPattern = mprintf("* %s *", zColumn);
    rc = sqlite3_strglob(zPattern, zDef)!=0;
    fossil_free(zPattern);
    fossil_free(zDef);
  }
  return rc;
}

/*
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
                         " WHERE name=='vfile'", db_name("localdb"));
  if( zVFileDef==0 ) return 0;

  /* If the "isexe" column is missing from the vfile table, then
  ** add it now.   This code added on 2010-03-06.  After all users have
  ** upgraded, this code can be safely deleted.
  */
  if( !strglob("* isexe *", zVFileDef) ){
    db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
  }

  /* If "islink"/"isLink" columns are missing from tables, then
  ** add them now.   This code added on 2011-01-17 and 2011-08-27.
  ** After all users have upgraded, this code can be safely deleted.
  */
  if( !strglob("* islink *", zVFileDef) ){
    db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
    if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
      db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
    }
    if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
      db_multi_exec("ALTER TABLE undo ADD COLUMN isLink BOOLEAN DEFAULT 0");
    }







|







|







920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
                         " WHERE name=='vfile'", db_name("localdb"));
  if( zVFileDef==0 ) return 0;

  /* If the "isexe" column is missing from the vfile table, then
  ** add it now.   This code added on 2010-03-06.  After all users have
  ** upgraded, this code can be safely deleted.
  */
  if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
    db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
  }

  /* If "islink"/"isLink" columns are missing from tables, then
  ** add them now.   This code added on 2011-01-17 and 2011-08-27.
  ** After all users have upgraded, this code can be safely deleted.
  */
  if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
    db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
    if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
      db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
    }
    if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
      db_multi_exec("ALTER TABLE undo ADD COLUMN isLink BOOLEAN DEFAULT 0");
    }
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
** This routine always opens the user database regardless of whether or
** not the repository database is found.  If the _FOSSIL_ or .fslckout file
** is found, it is attached to the open database connection too.
*/
int db_open_local(const char *zDbName){
  int i, n;
  char zPwd[2000];
  static const char aDbName[][10] = { "_FOSSIL_", ".fslckout", ".fos" };

  if( g.localOpen ) return 1;
  file_getcwd(zPwd, sizeof(zPwd)-20);
  n = strlen(zPwd);
  while( n>0 ){
    for(i=0; i<count(aDbName); i++){
      sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "/%s", aDbName[i]);
      if( isValidLocalDb(zPwd) ){
        /* Found a valid checkout database file */

        zPwd[n] = 0;
        while( n>0 && zPwd[n-1]=='/' ){
          n--;
          zPwd[n] = 0;
        }
        g.zLocalRoot = mprintf("%s/", zPwd);
        g.localOpen = 1;







|









>







963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
** This routine always opens the user database regardless of whether or
** not the repository database is found.  If the _FOSSIL_ or .fslckout file
** is found, it is attached to the open database connection too.
*/
int db_open_local(const char *zDbName){
  int i, n;
  char zPwd[2000];
  static const char *(aDbName[]) = { "_FOSSIL_", ".fslckout", ".fos" };

  if( g.localOpen ) return 1;
  file_getcwd(zPwd, sizeof(zPwd)-20);
  n = strlen(zPwd);
  while( n>0 ){
    for(i=0; i<count(aDbName); i++){
      sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "/%s", aDbName[i]);
      if( isValidLocalDb(zPwd) ){
        /* Found a valid checkout database file */
        g.zLocalDbName = mprintf("%s", zPwd);
        zPwd[n] = 0;
        while( n>0 && zPwd[n-1]=='/' ){
          n--;
          zPwd[n] = 0;
        }
        g.zLocalRoot = mprintf("%s/", zPwd);
        g.localOpen = 1;
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137

/*
** Return TRUE if the schema is out-of-date
*/
int db_schema_is_outofdate(void){
  return db_exists("SELECT 1 FROM config"
                   " WHERE name='aux-schema'"
                   "   AND value<>'%s'", AUX_SCHEMA);
}

/*
** Return true if the database is writeable
*/
int db_is_writeable(const char *zName){
  return g.db!=0 && !sqlite3_db_readonly(g.db, db_name(zName));







|







1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138

/*
** Return TRUE if the schema is out-of-date
*/
int db_schema_is_outofdate(void){
  return db_exists("SELECT 1 FROM config"
                   " WHERE name='aux-schema'"
                   "   AND value<>%Q", AUX_SCHEMA);
}

/*
** Return true if the database is writeable
*/
int db_is_writeable(const char *zName){
  return g.db!=0 && !sqlite3_db_readonly(g.db, db_name(zName));
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
  if( !optional ){
    db_multi_exec(
        "INSERT INTO config(name,value,mtime)"
        " VALUES('server-code', lower(hex(randomblob(20))),now());"
        "INSERT INTO config(name,value,mtime)"
        " VALUES('project-code', lower(hex(randomblob(20))),now());"
    );
  }else{
    if( db_get("server-code", 0)==0 ) {
      db_optional_sql("repository",
          "INSERT INTO config(name,value,mtime)"
          " VALUES('server-code', lower(hex(randomblob(20))),now());"
      );
    }
    if( db_get("project-code", 0)==0 ) {
      db_optional_sql("repository",
          "INSERT INTO config(name,value,mtime)"
          " VALUES('project-code', lower(hex(randomblob(20))),now());"
      );
    }
  }
}

/*
** Return a pointer to a string that contains the RHS of an IN operator
** that will select CONFIG table names that are in the list of control
** settings.
*/
const char *db_setting_inop_rhs(){
  Blob x;
  int i;
  const char *zSep = "";

  blob_zero(&x);
  blob_append(&x, "(", 1);
  for(i=0; ctrlSettings[i].name; i++){
    blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
    zSep = ",";
  }
  blob_append(&x, ")", 1);
  return blob_str(&x);
}

/*
** Fill an empty repository database with the basic information for a
** repository. This function is shared between 'create_repository_cmd'
** ('new') and 'reconstruct_cmd' ('reconstruct'), both of which create
** new repositories.







|

|





|


















|

|


|
|







1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
  if( !optional ){
    db_multi_exec(
        "INSERT INTO config(name,value,mtime)"
        " VALUES('server-code', lower(hex(randomblob(20))),now());"
        "INSERT INTO config(name,value,mtime)"
        " VALUES('project-code', lower(hex(randomblob(20))),now());"
    );
  }else if( db_is_writeable("repository") ){
    if( db_get("server-code", 0)==0 ) {
      db_multi_exec(
          "INSERT INTO config(name,value,mtime)"
          " VALUES('server-code', lower(hex(randomblob(20))),now());"
      );
    }
    if( db_get("project-code", 0)==0 ) {
      db_multi_exec(
          "INSERT INTO config(name,value,mtime)"
          " VALUES('project-code', lower(hex(randomblob(20))),now());"
      );
    }
  }
}

/*
** Return a pointer to a string that contains the RHS of an IN operator
** that will select CONFIG table names that are in the list of control
** settings.
*/
const char *db_setting_inop_rhs(){
  Blob x;
  int i;
  const char *zSep = "";

  blob_zero(&x);
  blob_append_sql(&x, "(");
  for(i=0; ctrlSettings[i].name; i++){
    blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
    zSep = ",";
  }
  blob_append_sql(&x, ")");
  return blob_sql_text(&x);
}

/*
** Fill an empty repository database with the basic information for a
** repository. This function is shared between 'create_repository_cmd'
** ('new') and 'reconstruct_cmd' ('reconstruct'), both of which create
** new repositories.
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522

1523
1524
1525
1526
1527
1528
1529
** associated permissions will be copied.
**
** Options:
**    --template      FILE      copy settings from repository file
**    --admin-user|-A USERNAME  select given USERNAME as admin user
**    --date-override DATETIME  use DATETIME as time of the initial checkin
**                              (default: do not create an initial checkin)
**    --empty                   create repository without project-id/server-id
**
** See also: clone
*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zTemplate;      /* Repository from which to copy settings */
  const char *zDate;          /* Date of the initial check-in */
  const char *zDefaultUser;   /* Optional name of the default user */
  int makeServerCodes;

  zTemplate = find_option("template",0,1);
  zDate = find_option("date-override",0,1);
  zDefaultUser = find_option("admin-user","A",1);
  makeServerCodes = find_option("empty", 0, 0)==0;


  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=3 ){
    usage("REPOSITORY-NAME");
  }
  db_create_repository(g.argv[2]);







<













|

>







1501
1502
1503
1504
1505
1506
1507

1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
** associated permissions will be copied.
**
** Options:
**    --template      FILE      copy settings from repository file
**    --admin-user|-A USERNAME  select given USERNAME as admin user
**    --date-override DATETIME  use DATETIME as time of the initial checkin
**                              (default: do not create an initial checkin)

**
** See also: clone
*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zTemplate;      /* Repository from which to copy settings */
  const char *zDate;          /* Date of the initial check-in */
  const char *zDefaultUser;   /* Optional name of the default user */
  int makeServerCodes;

  zTemplate = find_option("template",0,1);
  zDate = find_option("date-override",0,1);
  zDefaultUser = find_option("admin-user","A",1);
  makeServerCodes = find_option("docker", 0, 0)==0;

  find_option("empty", 0, 0); /* deprecated */
  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=3 ){
    usage("REPOSITORY-NAME");
  }
  db_create_repository(g.argv[2]);
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
** as follows:
**
**       ckout:%s
**
** Where %s is the checkout root.  The value is the repository file.
*/
void db_record_repository_filename(const char *zName){
  const char *zCollation;
  char *zRepoSetting;
  char *zCkoutSetting;
  Blob full;
  if( zName==0 ){
    if( !g.localOpen ) return;
    zName = db_repository_filename();
  }
  file_canonical_name(zName, &full, 0);
  zCollation = filename_collation();
  db_swap_connections();
  zRepoSetting = mprintf("repo:%q", blob_str(&full));
  db_multi_exec(
     "DELETE FROM global_config WHERE name %s = '%s';",
     zCollation, zRepoSetting
  );
  db_multi_exec(
     "INSERT OR IGNORE INTO global_config(name,value)"
     "VALUES('%s',1);",
     zRepoSetting
  );
  fossil_free(zRepoSetting);
  if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
    Blob localRoot;
    file_canonical_name(g.zLocalRoot, &localRoot, 1);
    zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
    db_multi_exec(
       "DELETE FROM global_config WHERE name %s = '%s';",
       zCollation, zCkoutSetting
    );
    db_multi_exec(
      "REPLACE INTO global_config(name, value)"
      "VALUES('%s','%q');",
      zCkoutSetting, blob_str(&full)
    );
    db_swap_connections();
    db_optional_sql("repository",
        "DELETE FROM config WHERE name %s = '%s';",
        zCollation, zCkoutSetting
    );
    db_optional_sql("repository",
        "REPLACE INTO config(name,value,mtime)"
        "VALUES('%s',1,now());",
        zCkoutSetting
    );
    fossil_free(zCkoutSetting);
    blob_reset(&localRoot);
  }else{
    db_swap_connections();
  }







<








|



|
|



|








|
|



|




|
|



|







2008
2009
2010
2011
2012
2013
2014

2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
** as follows:
**
**       ckout:%s
**
** Where %s is the checkout root.  The value is the repository file.
*/
void db_record_repository_filename(const char *zName){

  char *zRepoSetting;
  char *zCkoutSetting;
  Blob full;
  if( zName==0 ){
    if( !g.localOpen ) return;
    zName = db_repository_filename();
  }
  file_canonical_name(zName, &full, 0);
  (void)filename_collation();  /* Initialize before connection swap */
  db_swap_connections();
  zRepoSetting = mprintf("repo:%q", blob_str(&full));
  db_multi_exec(
     "DELETE FROM global_config WHERE name %s = %Q;",
     filename_collation(), zRepoSetting
  );
  db_multi_exec(
     "INSERT OR IGNORE INTO global_config(name,value)"
     "VALUES(%Q,1);",
     zRepoSetting
  );
  fossil_free(zRepoSetting);
  if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
    Blob localRoot;
    file_canonical_name(g.zLocalRoot, &localRoot, 1);
    zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
    db_multi_exec(
       "DELETE FROM global_config WHERE name %s = %Q;",
       filename_collation(), zCkoutSetting
    );
    db_multi_exec(
      "REPLACE INTO global_config(name, value)"
      "VALUES(%Q,%Q);",
      zCkoutSetting, blob_str(&full)
    );
    db_swap_connections();
    db_optional_sql("repository",
        "DELETE FROM config WHERE name %s = %Q;",
        filename_collation(), zCkoutSetting
    );
    db_optional_sql("repository",
        "REPLACE INTO config(name,value,mtime)"
        "VALUES(%Q,1,now());",
        zCkoutSetting
    );
    fossil_free(zCkoutSetting);
    blob_reset(&localRoot);
  }else{
    db_swap_connections();
  }
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
          blob_append(&newSql, zOrigSql, j);
          blob_append(&newSql, "PRIMARY KEY", -1);
          zOrigSql += j+6;
          j = -1;
        }
      }
      blob_append(&newSql, zOrigSql, -1);
      blob_appendf(&allSql,
         "ALTER TABLE %s RENAME TO x_%s;\n"
         "%s WITHOUT ROWID;\n"
         "INSERT INTO %s SELECT * FROM x_%s;\n"
         "DROP TABLE x_%s;\n",
         zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
      );
      fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
      blob_reset(&newSql);
    }
    blob_appendf(&allSql, "COMMIT;\n");
    db_finalize(&q);
    if( dryRun ){
      fossil_print("SQL that would have been evaluated:\n");
      fossil_print("-------------------------------------------------------------\n");
      fossil_print("%s", blob_str(&allSql));
    }else{
      db_multi_exec("%s", blob_str(&allSql));
    }
    blob_reset(&allSql);
    db_close(1);
  }
}







|
|

|
|
|




|




|

|





2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
          blob_append(&newSql, zOrigSql, j);
          blob_append(&newSql, "PRIMARY KEY", -1);
          zOrigSql += j+6;
          j = -1;
        }
      }
      blob_append(&newSql, zOrigSql, -1);
      blob_append_sql(&allSql,
         "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
         "%s WITHOUT ROWID;\n"
         "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
         "DROP TABLE \"x_%w\";\n",
         zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
      );
      fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
      blob_reset(&newSql);
    }
    blob_append_sql(&allSql, "COMMIT;\n");
    db_finalize(&q);
    if( dryRun ){
      fossil_print("SQL that would have been evaluated:\n");
      fossil_print("-------------------------------------------------------------\n");
      fossil_print("%s", blob_sql_text(&allSql));
    }else{
      db_multi_exec("%s", blob_sql_text(&allSql));
    }
    blob_reset(&allSql);
    db_close(1);
  }
}
Changes to src/delta.c.
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#if INTERFACE
/*
** The "u32" type must be an unsigned 32-bit integer.  Adjust this
*/
typedef unsigned int u32;

/*
** Must be a 16-bit value 
*/
typedef short int s16;
typedef unsigned short int u16;

#endif /* INTERFACE */

/*
** The width of a hash window in bytes.  The algorithm only works if this
** is a power of 2.
*/
#define NHASH 16

/*
** The current state of the rolling hash.
**
** z[] holds the values that have been hashed.  z[] is a circular buffer.
** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of 
** the window.
**
** Hash.a is the sum of all elements of hash.z[].  Hash.b is a weighted
** sum.  Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
** (Each index for z[] should be module NHASH, of course.  The %NHASH operator
** is omitted in the prior expression for brevity.)
*/







|
















|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#if INTERFACE
/*
** The "u32" type must be an unsigned 32-bit integer.  Adjust this
*/
typedef unsigned int u32;

/*
** Must be a 16-bit value
*/
typedef short int s16;
typedef unsigned short int u16;

#endif /* INTERFACE */

/*
** The width of a hash window in bytes.  The algorithm only works if this
** is a power of 2.
*/
#define NHASH 16

/*
** The current state of the rolling hash.
**
** z[] holds the values that have been hashed.  z[] is a circular buffer.
** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
** the window.
**
** Hash.a is the sum of all elements of hash.z[].  Hash.b is a weighted
** sum.  Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
** (Each index for z[] should be module NHASH, of course.  The %NHASH operator
** is omitted in the prior expression for brevity.)
*/
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  return (pHash->a & 0xffff) | (((u32)(pHash->b & 0xffff))<<16);
}

/*
** Write an base-64 integer into the given buffer.
*/
static void putInt(unsigned int v, char **pz){
  static const char zDigits[] = 
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
  /*  123456789 123456789 123456789 123456789 123456789 123456789 123 */
  int i, j;
  char zBuf[20];
  if( v==0 ){
    *(*pz)++ = '0';
    return;







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  return (pHash->a & 0xffff) | (((u32)(pHash->b & 0xffff))<<16);
}

/*
** Write an base-64 integer into the given buffer.
*/
static void putInt(unsigned int v, char **pz){
  static const char zDigits[] =
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
  /*  123456789 123456789 123456789 123456789 123456789 123456789 123 */
  int i, j;
  char zBuf[20];
  if( v==0 ){
    *(*pz)++ = '0';
    return;
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  }
  return sum3;
}

/*
** Create a new delta.
**
** The delta is written into a preallocated buffer, zDelta, which 
** should be at least 60 bytes longer than the target file, zOut.
** The delta string will be NUL-terminated, but it might also contain
** embedded NUL characters if either the zSrc or zOut files are
** binary.  This function returns the length of the delta string
** in bytes, excluding the final NUL terminator character.
**
** Output Format:
**
** The delta begins with a base64 number followed by a newline.  This
** number is the number of bytes in the TARGET file.  Thus, given a
** delta file z, a program can compute the size of the output file
** simply by reading the first line and decoding the base-64 number
** found there.  The delta_output_size() routine does exactly this.
**
** After the initial size number, the delta consists of a series of
** literal text segments and commands to copy from the SOURCE file.  
** A copy command looks like this:
**
**     NNN@MMM,
**
** where NNN is the number of bytes to be copied and MMM is the offset
** into the source file of the first byte (both base-64).   If NNN is 0
** it means copy the rest of the input file.  Literal text is like this:







|















|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  }
  return sum3;
}

/*
** Create a new delta.
**
** The delta is written into a preallocated buffer, zDelta, which
** should be at least 60 bytes longer than the target file, zOut.
** The delta string will be NUL-terminated, but it might also contain
** embedded NUL characters if either the zSrc or zOut files are
** binary.  This function returns the length of the delta string
** in bytes, excluding the final NUL terminator character.
**
** Output Format:
**
** The delta begins with a base64 number followed by a newline.  This
** number is the number of bytes in the TARGET file.  Thus, given a
** delta file z, a program can compute the size of the output file
** simply by reading the first line and decoding the base-64 number
** found there.  The delta_output_size() routine does exactly this.
**
** After the initial size number, the delta consists of a series of
** literal text segments and commands to copy from the SOURCE file.
** A copy command looks like this:
**
**     NNN@MMM,
**
** where NNN is the number of bytes to be copied and MMM is the offset
** into the source file of the first byte (both base-64).   If NNN is 0
** it means copy the rest of the input file.  Literal text is like this:
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
** Next we begin scanning the target file using a sliding 16-byte
** window.  The hash of the 16-byte window in the target is used to
** search for a matching section in the source file.  When a match
** is found, a copy command is added to the delta.  An effort is
** made to extend the matching section to regions that come before
** and after the 16-byte hash window.  A copy command is only issued
** if the result would use less space that just quoting the text
** literally. Literal text is added to the delta for sections that 
** do not match or which can not be encoded efficiently using copy
** commands.
*/
int delta_create(
  const char *zSrc,      /* The source or pattern file */
  unsigned int lenSrc,   /* Length of the source file */
  const char *zOut,      /* The target file */







|







281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
** Next we begin scanning the target file using a sliding 16-byte
** window.  The hash of the 16-byte window in the target is used to
** search for a matching section in the source file.  When a match
** is found, a copy command is added to the delta.  An effort is
** made to extend the matching section to regions that come before
** and after the 16-byte hash window.  A copy command is only issued
** if the result would use less space that just quoting the text
** literally. Literal text is added to the delta for sections that
** do not match or which can not be encoded efficiently using copy
** commands.
*/
int delta_create(
  const char *zSrc,      /* The source or pattern file */
  unsigned int lenSrc,   /* Length of the source file */
  const char *zOut,      /* The target file */
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
      int limit = 250;

      hv = hash_32bit(&h) % nHash;
      DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
      iBlock = landmark[hv];
      while( iBlock>=0 && (limit--)>0 ){
        /*
        ** The hash window has identified a potential match against 
        ** landmark block iBlock.  But we need to investigate further.
        ** 
        ** Look for a region in zOut that matches zSrc. Anchor the search
        ** at zSrc[iSrc] and zOut[base+i].  Do not include anything prior to
        ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
        **
        ** Set cnt equal to the length of the match and set ofst so that
        ** zSrc[ofst] is the first element of the match.  litsz is the number
        ** of characters between zOut[base] and the beginning of the match.







|

|







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
      int limit = 250;

      hv = hash_32bit(&h) % nHash;
      DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
      iBlock = landmark[hv];
      while( iBlock>=0 && (limit--)>0 ){
        /*
        ** The hash window has identified a potential match against
        ** landmark block iBlock.  But we need to investigate further.
        **
        ** Look for a region in zOut that matches zSrc. Anchor the search
        ** at zSrc[iSrc] and zOut[base+i].  Do not include anything prior to
        ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
        **
        ** Set cnt equal to the length of the match and set ofst so that
        ** zSrc[ofst] is the first element of the match.  litsz is the number
        ** of characters between zOut[base] and the beginning of the match.
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
    memcpy(zDelta, &zOut[base], lenOut-base);
    zDelta += lenOut-base;
  }
  /* Output the final checksum record. */
  putInt(checksum(zOut, lenOut), &zDelta);
  *(zDelta++) = ';';
  fossil_free(collide);
  return zDelta - zOrigDelta; 
}

/*
** Return the size (in bytes) of the output from applying
** a delta. 
**
** This routine is provided so that an procedure that is able
** to call delta_apply() can learn how much space is required
** for the output and hence allocate nor more space that is really
** needed.
*/
int delta_output_size(const char *zDelta, int lenDelta){







|




|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
    memcpy(zDelta, &zOut[base], lenOut-base);
    zDelta += lenOut-base;
  }
  /* Output the final checksum record. */
  putInt(checksum(zOut, lenOut), &zDelta);
  *(zDelta++) = ';';
  fossil_free(collide);
  return zDelta - zOrigDelta;
}

/*
** Return the size (in bytes) of the output from applying
** a delta.
**
** This routine is provided so that an procedure that is able
** to call delta_apply() can learn how much space is required
** for the output and hence allocate nor more space that is really
** needed.
*/
int delta_output_size(const char *zDelta, int lenDelta){
Changes to src/descendants.c.
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  
  /* We should be done with options.. */
  verify_all_options();

  if( recomputeFlag ) leaf_rebuild();
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_tty(), -1);
  blob_appendf(&sql, " AND blob.rid IN leaf");
  if( showClosed ){
    blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
  }else if( !showAll ){
    blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
  }
  if( byBranch ){
    db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
                   " event.mtime DESC",
                   blob_str(&sql));
  }else{
    db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
  }
  blob_reset(&sql);
  n = 0;
  while( db_step(&q)==SQLITE_ROW ){
    const char *zId = db_column_text(&q, 1);
    const char *zDate = db_column_text(&q, 2);
    const char *zCom = db_column_text(&q, 3);







|

|

|




|

|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  
  /* We should be done with options.. */
  verify_all_options();

  if( recomputeFlag ) leaf_rebuild();
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_tty(), -1);
  blob_append_sql(&sql, " AND blob.rid IN leaf");
  if( showClosed ){
    blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
  }else if( !showAll ){
    blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
  }
  if( byBranch ){
    db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
                   " event.mtime DESC",
                   blob_sql_text(&sql));
  }else{
    db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
  }
  blob_reset(&sql);
  n = 0;
  while( db_step(&q)==SQLITE_ROW ){
    const char *zId = db_column_text(&q, 1);
    const char *zDate = db_column_text(&q, 2);
    const char *zCom = db_column_text(&q, 3);
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  }else if( showClosed ){
    @ <h1>Closed leaves:</h1>
  }else{
    @ <h1>Open leaves:</h1>
  }
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_www(), -1);
  blob_appendf(&sql, " AND blob.rid IN leaf");
  if( showClosed ){
    blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
  }else if( !showAll ){
    blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
  }
  db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
  blob_reset(&sql);
  www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
  db_finalize(&q);
  @ <br />
  style_footer();
}








|

|

|

|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  }else if( showClosed ){
    @ <h1>Closed leaves:</h1>
  }else{
    @ <h1>Open leaves:</h1>
  }
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_www(), -1);
  blob_append_sql(&sql, " AND blob.rid IN leaf");
  if( showClosed ){
    blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
  }else if( !showAll ){
    blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
  }
  db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
  blob_reset(&sql);
  www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
  db_finalize(&q);
  @ <br />
  style_footer();
}

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  Bag pending;
  Stmt ins;
  Stmt q;
  int rid;

  bag_init(&seen);
  bag_init(&pending);
  db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab);
  db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
  while( db_step(&q)==SQLITE_ROW ){
    int mid = db_column_int(&q, 0);
    bag_insert(&pending, mid);
    bag_insert(&seen, mid);
    db_bind_int(&ins, ":rid", mid);
    db_step(&ins);







|







506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  Bag pending;
  Stmt ins;
  Stmt q;
  int rid;

  bag_init(&seen);
  bag_init(&pending);
  db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab);
  db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
  while( db_step(&q)==SQLITE_ROW ){
    int mid = db_column_int(&q, 0);
    bag_insert(&pending, mid);
    bag_insert(&seen, mid);
    db_bind_int(&ins, ":rid", mid);
    db_step(&ins);
Added src/diff.tcl.


























































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
set prog {
package require Tk

array set CFG {
  TITLE      {Fossil Diff}
  LN_COL_BG  #dddddd
  LN_COL_FG  #444444
  TXT_COL_BG #ffffff
  TXT_COL_FG #000000
  MKR_COL_BG #444444
  MKR_COL_FG #dddddd
  CHNG_BG    #d0d0ff
  ADD_BG     #c0ffc0
  RM_BG      #ffc0c0
  HR_FG      #888888
  HR_PAD_TOP 4
  HR_PAD_BTM 8
  FN_BG      #444444
  FN_FG      #ffffff
  FN_PAD     5
  ERR_FG     #ee0000
  PADX       5
  WIDTH      80
  HEIGHT     45
  LB_HEIGHT  25
}

if {![namespace exists ttk]} {
  interp alias {} ::ttk::scrollbar {} ::scrollbar
  interp alias {} ::ttk::menubutton {} ::menubutton
}

proc dehtml {x} {
  set x [regsub -all {<[^>]*>} $x {}]
  return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
}

proc cols {} {
  return [list .lnA .txtA .mkr .lnB .txtB]
}

proc colType {c} {
  regexp {[a-z]+} $c type
  return $type
}

proc getLine {difftxt N iivar} {
  upvar $iivar ii
  if {$ii>=$N} {return -1}
  set x [lindex $difftxt $ii]
  incr ii
  return $x
}

proc readDiffs {fossilcmd} {
  global difftxt
  if {![info exists difftxt]} {
    set in [open $fossilcmd r]
    fconfigure $in -encoding utf-8
    set difftxt [split [read $in] \n]
    close $in
  }
  set N [llength $difftxt]
  set ii 0
  set nDiffs 0
  array set widths {txt 0 ln 0 mkr 0}
  while {[set line [getLine $difftxt $N ii]] != -1} {
    set fn2 {}
    if {![regexp {^=+ (.*?) =+ versus =+ (.*?) =+$} $line all fn fn2]
     && ![regexp {^=+ (.*?) =+$} $line all fn]
    } {
      continue
    }
    set errMsg ""
    set line [getLine $difftxt $N ii]
    if {[string compare -length 6 $line "<table"]
     && ![regexp {<p[^>]*>(.+)} $line - errMsg]} {
      continue
    }
    incr nDiffs
    set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
    .wfiles.lb insert end $fn

    foreach c [cols] {
      if {$nDiffs > 1} {
        $c insert end \n -
      }
      if {[colType $c] eq "txt"} {
        $c insert end $fn\n fn
        if {$fn2!=""} {set fn $fn2}
      } else {
        $c insert end \n fn
      }
      $c insert end \n -

      if {$errMsg ne ""} continue
      while {[getLine $difftxt $N ii] ne "<pre>"} continue
      set type [colType $c]
      set str {}
      while {[set line [getLine $difftxt $N ii]] ne "</pre>"} {
        set len [string length [dehtml $line]]
        if {$len > $widths($type)} {
          set widths($type) $len
        }
        append str $line\n
      }

      set re {<span class="diff([a-z]+)">([^<]*)</span>}
      # Use \r as separator since it can't appear in the diff output (it gets
      # converted to a space).
      set str [regsub -all $re $str "\r\\1\r\\2\r"]
      foreach {pre class mid} [split $str \r] {
        if {$class ne ""} {
          $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
        } else {
          $c insert end [dehtml $pre] -
        }
      }
    }

    if {$errMsg ne ""} {
      foreach c {.txtA .txtB} {$c insert end [string trim $errMsg] err}
      foreach c [cols] {$c insert end \n -}
    }
  }

  foreach c [cols] {
    set type [colType $c]
    if {$type ne "txt"} {
      $c config -width $widths($type)
    }
    $c config -state disabled
  }
  if {$nDiffs <= [.wfiles.lb cget -height]} {
    .wfiles.lb config -height $nDiffs
    grid remove .wfiles.sb
  }

  return $nDiffs
}

proc viewDiff {idx} {
  .txtA yview $idx
  .txtA xview moveto 0
}

proc cycleDiffs {{reverse 0}} {
  if {$reverse} {
    set range [.txtA tag prevrange fn @0,0 1.0]
    if {$range eq ""} {
      viewDiff {fn.last -1c}
    } else {
      viewDiff [lindex $range 0]
    }
  } else {
    set range [.txtA tag nextrange fn {@0,0 +1c} end]
    if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
      viewDiff fn.first
    } else {
      viewDiff [lindex $range 0]
    }
  }
}

proc xvis {col} {
  set view [$col xview]
  return [expr {[lindex $view 1]-[lindex $view 0]}]
}

proc scroll-x {args} {
  set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
  eval $c xview $args
}

interp alias {} scroll-y {} .txtA yview

proc noop {args} {}

proc enableSync {axis} {
  update idletasks
  interp alias {} sync-$axis {}
  rename _sync-$axis sync-$axis
}

proc disableSync {axis} {
  rename sync-$axis _sync-$axis
  interp alias {} sync-$axis {} noop
}

proc sync-x {col first last} {
  disableSync x
  $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
  foreach side {A B} {
    set sb .sbx$side
    set xview [.txt$side xview]
    if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} {
      grid $sb
      eval $sb set $xview
    } else {
      grid remove $sb
    }
  }
  enableSync x
}

proc sync-y {first last} {
  disableSync y
  foreach c [cols] {
    $c yview moveto $first
  }
  if {$first > 0 || $last < 1} {
    grid .sby
    .sby set $first $last
  } else {
    grid remove .sby
  }
  enableSync y
}

wm withdraw .
wm title . $CFG(TITLE)
wm iconname . $CFG(TITLE)
bind . <q> exit
bind . <Destroy> {after 0 exit}
bind . <Tab> {cycleDiffs; break}
bind . <<PrevWindow>> {cycleDiffs 1; break}
bind . <Return> {
  event generate .bb.files <1>
  event generate .bb.files <ButtonRelease-1>
  break
}
foreach {key axis args} {
  Up    y {scroll -5 units}
  Down  y {scroll 5 units}
  Left  x {scroll -5 units}
  Right x {scroll 5 units}
  Prior y {scroll -1 page}
  Next  y {scroll 1 page}
  Home  y {moveto 0}
  End   y {moveto 1}
} {
  bind . <$key> "scroll-$axis $args; break"
  bind . <Shift-$key> continue
}

frame .bb
::ttk::menubutton .bb.files -text "Files"
toplevel .wfiles
wm withdraw .wfiles
update idletasks
wm transient .wfiles .
wm overrideredirect .wfiles 1
listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
  -yscroll {.wfiles.sb set}
::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
grid .wfiles.lb .wfiles.sb -sticky ns
bind .bb.files <1> {
  set x [winfo rootx %W]
  set y [expr {[winfo rooty %W]+[winfo height %W]}]
  wm geometry .wfiles +$x+$y
  wm deiconify .wfiles
  focus .wfiles.lb
}
bind .wfiles <FocusOut> {wm withdraw .wfiles}
bind .wfiles <Escape> {focus .}
foreach evt {1 Return} {
  bind .wfiles.lb <$evt> {
    catch {
      set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
      viewDiff $idx
    }
    focus .
    break
  }
}
bind .wfiles.lb <Motion> {
  %W selection clear 0 end
  %W selection set @%x,%y
}

foreach {side syncCol} {A .txtB B .txtA} {
  set ln .ln$side
  text $ln
  $ln tag config - -justify right

  set txt .txt$side
  text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
    -xscroll "sync-x $syncCol"
  catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
  foreach tag {add rm chng} {
    $txt tag config $tag -background $CFG([string toupper $tag]_BG)
    $txt tag lower $tag
  }
  $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
    -justify center
  $txt tag config err -foreground $CFG(ERR_FG)
}
text .mkr

foreach c [cols] {
  set keyPrefix [string toupper [colType $c]]_COL_
  if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}}
  $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
    -padx $CFG(PADX) -yscroll sync-y
  $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
     -foreground $CFG(HR_FG)
  $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
  bindtags $c ". $c Text all"
  bind $c <1> {focus %W}
}

::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
frame .spacer

if {[readDiffs $fossilcmd] == 0} {
  tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
  exit
}
update idletasks

proc saveDiff {} {
  set fn [tk_getSaveFile]
  if {$fn==""} return
  set out [open $fn wb]
  puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
  puts $out "# to see the graphical diff.\n#"
  puts $out "set fossilcmd {}"
  puts $out "set prog [list $::prog]"
  puts $out "set difftxt \173"
  foreach e $::difftxt {puts $out [list $e]}
  puts $out "\175"
  puts $out "eval \$prog"
  close $out
}
proc invertDiff {} {
  global CFG
  array set x [grid info .txtA]
  if {$x(-column)==1} {
    grid config .lnB -column 0
    grid config .txtB -column 1
    .txtB tag config add -background $CFG(RM_BG)
    grid config .lnA -column 3
    grid config .txtA -column 4
    .txtA tag config rm -background $CFG(ADD_BG)
  } else {
    grid config .lnA -column 0
    grid config .txtA -column 1
    .txtA tag config rm -background $CFG(RM_BG)
    grid config .lnB -column 3
    grid config .txtB -column 4
    .txtB tag config add -background $CFG(ADD_BG)
  }
  .mkr config -state normal
  set clt [.mkr search -all < 1.0 end]
  set cgt [.mkr search -all > 1.0 end]
  foreach c $clt {.mkr replace $c "$c +1 chars" >}
  foreach c $cgt {.mkr replace $c "$c +1 chars" <}
  .mkr config -state disabled
}
::ttk::button .bb.quit -text {Quit} -command exit
::ttk::button .bb.invert -text {Invert} -command invertDiff
::ttk::button .bb.save -text {Save As...} -command saveDiff
pack .bb.quit .bb.invert -side left
if {$fossilcmd!=""} {pack .bb.save -side left}
pack .bb.files -side left
grid rowconfigure . 1 -weight 1
grid columnconfigure . 1 -weight 1
grid columnconfigure . 4 -weight 1
grid .bb -row 0 -columnspan 6
eval grid [cols] -row 1 -sticky nsew
grid .sby -row 1 -column 5 -sticky ns
grid .sbxA -row 2 -columnspan 2 -sticky ew
grid .spacer -row 2 -column 2
grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew

.spacer config -height [winfo height .sbxA]
wm deiconify .
}
eval $prog
Changes to src/diffcmd.c.
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    int cnt = 0;
    Blob nameFile1;    /* Name of temporary file to old pFile1 content */
    Blob cmd;          /* Text of command to run */

    if( !fIncludeBinary ){
      Blob file2;
      if( isBin1 ){
        fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
        return;
      }
      if( zBinGlob ){
        Glob *pBinary = glob_create(zBinGlob);
        if( glob_match(pBinary, zName) ){
          fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
          glob_free(pBinary);
          return;
        }
        glob_free(pBinary);
      }
      blob_zero(&file2);
      if( file_wd_size(zFile2)>=0 ){
        if( file_wd_islink(zFile2) ){
          blob_read_link(&file2, zFile2);
        }else{
          blob_read_from_file(&file2, zFile2);
        }
      }
      if( looks_like_binary(&file2) ){
        fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
        blob_reset(&file2);
        return;
      }
      blob_reset(&file2);
    }

    /* Construct a temporary file to hold pFile1 based on the name of







|





|














|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    int cnt = 0;
    Blob nameFile1;    /* Name of temporary file to old pFile1 content */
    Blob cmd;          /* Text of command to run */

    if( !fIncludeBinary ){
      Blob file2;
      if( isBin1 ){
        fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
        return;
      }
      if( zBinGlob ){
        Glob *pBinary = glob_create(zBinGlob);
        if( glob_match(pBinary, zName) ){
          fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
          glob_free(pBinary);
          return;
        }
        glob_free(pBinary);
      }
      blob_zero(&file2);
      if( file_wd_size(zFile2)>=0 ){
        if( file_wd_islink(zFile2) ){
          blob_read_link(&file2, zFile2);
        }else{
          blob_read_from_file(&file2, zFile2);
        }
      }
      if( looks_like_binary(&file2) ){
        fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
        blob_reset(&file2);
        return;
      }
      blob_reset(&file2);
    }

    /* Construct a temporary file to hold pFile1 based on the name of
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  }else{
    Blob cmd;
    char zTemp1[300];
    char zTemp2[300];

    if( !fIncludeBinary ){
      if( isBin1 || isBin2 ){
        fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
        return;
      }
      if( zBinGlob ){
        Glob *pBinary = glob_create(zBinGlob);
        if( glob_match(pBinary, zName) ){
          fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
          glob_free(pBinary);
          return;
        }
        glob_free(pBinary);
      }
    }








|





|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  }else{
    Blob cmd;
    char zTemp1[300];
    char zTemp2[300];

    if( !fIncludeBinary ){
      if( isBin1 || isBin2 ){
        fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
        return;
      }
      if( zBinGlob ){
        Glob *pBinary = glob_create(zBinGlob);
        if( glob_match(pBinary, zName) ){
          fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
          glob_free(pBinary);
          return;
        }
        glob_free(pBinary);
      }
    }

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
  Blob content;
  int isLink;
  int isBin;
  file_tree_name(zFileTreeName, &fname, 1);
  historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
                             fIncludeBinary ? 0 : &isBin, 0);
  if( !isLink != !file_wd_islink(zFrom) ){
    fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
  }else{
    diff_file(&content, isBin, zFileTreeName, zFileTreeName,
              zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
  }
  blob_reset(&content);
  blob_reset(&fname);
}







|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
  Blob content;
  int isLink;
  int isBin;
  file_tree_name(zFileTreeName, &fname, 1);
  historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
                             fIncludeBinary ? 0 : &isBin, 0);
  if( !isLink != !file_wd_islink(zFrom) ){
    fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
  }else{
    diff_file(&content, isBin, zFileTreeName, zFileTreeName,
              zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
  }
  blob_reset(&content);
  blob_reset(&fname);
}
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  db_begin_transaction();
  if( zFrom ){
    int rid = name_to_typed_rid(zFrom, "ci");
    if( !is_a_version(rid) ){
      fossil_fatal("no such check-in: %s", zFrom);
    }
    load_vfile_from_rid(rid);
    blob_appendf(&sql,
      "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
      "  FROM vfile v1, vfile v2 "
      " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
      "   AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
      "UNION "
      "SELECT pathname, 1, 0, 0, 0, islink"
      "  FROM vfile v1"
      " WHERE v1.vid=%d"
      "   AND NOT EXISTS(SELECT 1 FROM vfile v2"
                        " WHERE v2.vid=%d AND v2.pathname=v1.pathname)"
      "UNION "
      "SELECT pathname, 0, 0, 1, 0, islink"
      "  FROM vfile v2"
      " WHERE v2.vid=%d"
      "   AND NOT EXISTS(SELECT 1 FROM vfile v1"
                        " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
      " ORDER BY 1",
      rid, vid, rid, vid, vid, rid
    );
  }else{
    blob_appendf(&sql,
      "SELECT pathname, deleted, chnged , rid==0, rid, islink"
      "  FROM vfile"
      " WHERE vid=%d"
      "   AND (deleted OR chnged OR rid==0)"
      " ORDER BY pathname",
      vid
    );
  }
  db_prepare(&q, blob_str(&sql));
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    int isDeleted = db_column_int(&q, 1);
    int isChnged = db_column_int(&q,2);
    int isNew = db_column_int(&q,3);
    int srcid = db_column_int(&q, 4);
    int isLink = db_column_int(&q, 5);







|




















|








|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  db_begin_transaction();
  if( zFrom ){
    int rid = name_to_typed_rid(zFrom, "ci");
    if( !is_a_version(rid) ){
      fossil_fatal("no such check-in: %s", zFrom);
    }
    load_vfile_from_rid(rid);
    blob_append_sql(&sql,
      "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
      "  FROM vfile v1, vfile v2 "
      " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
      "   AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
      "UNION "
      "SELECT pathname, 1, 0, 0, 0, islink"
      "  FROM vfile v1"
      " WHERE v1.vid=%d"
      "   AND NOT EXISTS(SELECT 1 FROM vfile v2"
                        " WHERE v2.vid=%d AND v2.pathname=v1.pathname)"
      "UNION "
      "SELECT pathname, 0, 0, 1, 0, islink"
      "  FROM vfile v2"
      " WHERE v2.vid=%d"
      "   AND NOT EXISTS(SELECT 1 FROM vfile v1"
                        " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
      " ORDER BY 1",
      rid, vid, rid, vid, vid, rid
    );
  }else{
    blob_append_sql(&sql,
      "SELECT pathname, deleted, chnged , rid==0, rid, islink"
      "  FROM vfile"
      " WHERE vid=%d"
      "   AND (deleted OR chnged OR rid==0)"
      " ORDER BY pathname",
      vid
    );
  }
  db_prepare(&q, "%s", blob_sql_text(&sql));
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    int isDeleted = db_column_int(&q, 1);
    int isChnged = db_column_int(&q,2);
    int isNew = db_column_int(&q,3);
    int srcid = db_column_int(&q, 4);
    int isLink = db_column_int(&q, 5);
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    }
    if( showDiff ){
      Blob content;
      int isBin;
      if( !isLink != !file_wd_islink(zFullName) ){
        diff_print_index(zPathname, diffFlags);
        diff_print_filenames(zPathname, zPathname, diffFlags);
        fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
        continue;
      }
      if( srcid>0 ){
        content_get(srcid, &content);
      }else{
        blob_zero(&content);
      }







|







406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    }
    if( showDiff ){
      Blob content;
      int isBin;
      if( !isLink != !file_wd_islink(zFullName) ){
        diff_print_index(zPathname, diffFlags);
        diff_print_filenames(zPathname, zPathname, diffFlags);
        fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
        continue;
      }
      if( srcid>0 ){
        content_get(srcid, &content);
      }else{
        blob_zero(&content);
      }
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  zName = blob_str(&fname);
  historical_version_of_file(zFrom, zName, &v1, &isLink1, 0,
                             fIncludeBinary ? 0 : &isBin1, 0);
  historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
                             fIncludeBinary ? 0 : &isBin2, 0);
  if( isLink1 != isLink2 ){
    diff_print_filenames(zName, zName, diffFlags);
    fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
  }else{
    diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
                  zBinGlob, fIncludeBinary, diffFlags);
  }
  blob_reset(&v1);
  blob_reset(&v2);
  blob_reset(&fname);







|







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  zName = blob_str(&fname);
  historical_version_of_file(zFrom, zName, &v1, &isLink1, 0,
                             fIncludeBinary ? 0 : &isBin1, 0);
  historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
                             fIncludeBinary ? 0 : &isBin2, 0);
  if( isLink1 != isLink2 ){
    diff_print_filenames(zName, zName, diffFlags);
    fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
  }else{
    diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
                  zBinGlob, fIncludeBinary, diffFlags);
  }
  blob_reset(&v1);
  blob_reset(&v2);
  blob_reset(&fname);
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
  }else{
    zDefault = 0;
    zName = "diff-command";
  }
  return db_get(zName, zDefault);
}

/* A Tcl/Tk script used to render diff output.
*/
static const char zDiffScript[] =
@ set prog {
@ package require Tk
@
@ array set CFG {
@   TITLE      {Fossil Diff}
@   LN_COL_BG  #dddddd
@   LN_COL_FG  #444444
@   TXT_COL_BG #ffffff
@   TXT_COL_FG #000000
@   MKR_COL_BG #444444
@   MKR_COL_FG #dddddd
@   CHNG_BG    #d0d0ff
@   ADD_BG     #c0ffc0
@   RM_BG      #ffc0c0
@   HR_FG      #888888
@   HR_PAD_TOP 4
@   HR_PAD_BTM 8
@   FN_BG      #444444
@   FN_FG      #ffffff
@   FN_PAD     5
@   ERR_FG     #ee0000
@   PADX       5
@   WIDTH      80
@   HEIGHT     45
@   LB_HEIGHT  25
@ }
@
@ if {![namespace exists ttk]} {
@   interp alias {} ::ttk::scrollbar {} ::scrollbar
@   interp alias {} ::ttk::menubutton {} ::menubutton
@ }
@
@ proc dehtml {x} {
@   set x [regsub -all {<[^>]*>} $x {}]
@   return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
@ }
@
@ proc cols {} {
@   return [list .lnA .txtA .mkr .lnB .txtB]
@ }
@
@ proc colType {c} {
@   regexp {[a-z]+} $c type
@   return $type
@ }
@
@ proc getLine {difftxt N iivar} {
@   upvar $iivar ii
@   if {$ii>=$N} {return -1}
@   set x [lindex $difftxt $ii]
@   incr ii
@   return $x
@ }
@
@ proc readDiffs {fossilcmd} {
@   global difftxt
@   if {![info exists difftxt]} {
@     set in [open $fossilcmd r]
@     fconfigure $in -encoding utf-8
@     set difftxt [split [read $in] \n]
@     close $in
@   }
@   set N [llength $difftxt]
@   set ii 0
@   set nDiffs 0
@   array set widths {txt 0 ln 0 mkr 0}
@   while {[set line [getLine $difftxt $N ii]] != -1} {
@     set fn2 {}
@     if {![regexp {^=+ (.*?) =+ versus =+ (.*?) =+$} $line all fn fn2]
@      && ![regexp {^=+ (.*?) =+$} $line all fn]
@     } {
@       continue
@     }
@     set errMsg ""
@     set line [getLine $difftxt $N ii]
@     if {[string compare -length 6 $line "<table"]
@      && ![regexp {<p[^>]*>(.+)} $line - errMsg]} {
@       continue
@     }
@     incr nDiffs
@     set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
@     .wfiles.lb insert end $fn
@
@     foreach c [cols] {
@       if {$nDiffs > 1} {
@         $c insert end \n -
@       }
@       if {[colType $c] eq "txt"} {
@         $c insert end $fn\n fn
@         if {$fn2!=""} {set fn $fn2}
@       } else {
@         $c insert end \n fn
@       }
@       $c insert end \n -
@
@       if {$errMsg ne ""} continue
@       while {[getLine $difftxt $N ii] ne "<pre>"} continue
@       set type [colType $c]
@       set str {}
@       while {[set line [getLine $difftxt $N ii]] ne "</pre>"} {
@         set len [string length [dehtml $line]]
@         if {$len > $widths($type)} {
@           set widths($type) $len
@         }
@         append str $line\n
@       }
@
@       set re {<span class="diff([a-z]+)">([^<]*)</span>}
@       # Use \r as separator since it can't appear in the diff output (it gets
@       # converted to a space).
@       set str [regsub -all $re $str "\r\\1\r\\2\r"]
@       foreach {pre class mid} [split $str \r] {
@         if {$class ne ""} {
@           $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
@         } else {
@           $c insert end [dehtml $pre] -
@         }
@       }
@     }
@
@     if {$errMsg ne ""} {
@       foreach c {.txtA .txtB} {$c insert end [string trim $errMsg] err}
@       foreach c [cols] {$c insert end \n -}
@     }
@   }
@
@   foreach c [cols] {
@     set type [colType $c]
@     if {$type ne "txt"} {
@       $c config -width $widths($type)
@     }
@     $c config -state disabled
@   }
@   if {$nDiffs <= [.wfiles.lb cget -height]} {
@     .wfiles.lb config -height $nDiffs
@     grid remove .wfiles.sb
@   }
@
@   return $nDiffs
@ }
@
@ proc viewDiff {idx} {
@   .txtA yview $idx
@   .txtA xview moveto 0
@ }
@
@ proc cycleDiffs {{reverse 0}} {
@   if {$reverse} {
@     set range [.txtA tag prevrange fn @0,0 1.0]
@     if {$range eq ""} {
@       viewDiff {fn.last -1c}
@     } else {
@       viewDiff [lindex $range 0]
@     }
@   } else {
@     set range [.txtA tag nextrange fn {@0,0 +1c} end]
@     if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
@       viewDiff fn.first
@     } else {
@       viewDiff [lindex $range 0]
@     }
@   }
@ }
@
@ proc xvis {col} {
@   set view [$col xview]
@   return [expr {[lindex $view 1]-[lindex $view 0]}]
@ }
@
@ proc scroll-x {args} {
@   set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
@   eval $c xview $args
@ }
@
@ interp alias {} scroll-y {} .txtA yview
@
@ proc noop {args} {}
@
@ proc enableSync {axis} {
@   update idletasks
@   interp alias {} sync-$axis {}
@   rename _sync-$axis sync-$axis
@ }
@
@ proc disableSync {axis} {
@   rename sync-$axis _sync-$axis
@   interp alias {} sync-$axis {} noop
@ }
@
@ proc sync-x {col first last} {
@   disableSync x
@   $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
@   foreach side {A B} {
@     set sb .sbx$side
@     set xview [.txt$side xview]
@     if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} {
@       grid $sb
@       eval $sb set $xview
@     } else {
@       grid remove $sb
@     }
@   }
@   enableSync x
@ }
@
@ proc sync-y {first last} {
@   disableSync y
@   foreach c [cols] {
@     $c yview moveto $first
@   }
@   if {$first > 0 || $last < 1} {
@     grid .sby
@     .sby set $first $last
@   } else {
@     grid remove .sby
@   }
@   enableSync y
@ }
@
@ wm withdraw .
@ wm title . $CFG(TITLE)
@ wm iconname . $CFG(TITLE)
@ bind . <q> exit
@ bind . <Destroy> {after 0 exit}
@ bind . <Tab> {cycleDiffs; break}
@ bind . <<PrevWindow>> {cycleDiffs 1; break}
@ bind . <Return> {
@   event generate .bb.files <1>
@   event generate .bb.files <ButtonRelease-1>
@   break
@ }
@ foreach {key axis args} {
@   Up    y {scroll -5 units}
@   Down  y {scroll 5 units}
@   Left  x {scroll -5 units}
@   Right x {scroll 5 units}
@   Prior y {scroll -1 page}
@   Next  y {scroll 1 page}
@   Home  y {moveto 0}
@   End   y {moveto 1}
@ } {
@   bind . <$key> "scroll-$axis $args; break"
@   bind . <Shift-$key> continue
@ }
@
@ frame .bb
@ ::ttk::menubutton .bb.files -text "Files"
@ toplevel .wfiles
@ wm withdraw .wfiles
@ update idletasks
@ wm transient .wfiles .
@ wm overrideredirect .wfiles 1
@ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
@   -yscroll {.wfiles.sb set}
@ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
@ grid .wfiles.lb .wfiles.sb -sticky ns
@ bind .bb.files <1> {
@   set x [winfo rootx %W]
@   set y [expr {[winfo rooty %W]+[winfo height %W]}]
@   wm geometry .wfiles +$x+$y
@   wm deiconify .wfiles
@   focus .wfiles.lb
@ }
@ bind .wfiles <FocusOut> {wm withdraw .wfiles}
@ bind .wfiles <Escape> {focus .}
@ foreach evt {1 Return} {
@   bind .wfiles.lb <$evt> {
@     catch {
@       set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
@       viewDiff $idx
@     }
@     focus .
@     break
@   }
@ }
@ bind .wfiles.lb <Motion> {
@   %W selection clear 0 end
@   %W selection set @%x,%y
@ }
@
@ foreach {side syncCol} {A .txtB B .txtA} {
@   set ln .ln$side
@   text $ln
@   $ln tag config - -justify right
@
@   set txt .txt$side
@   text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
@     -xscroll "sync-x $syncCol"
@   catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
@   foreach tag {add rm chng} {
@     $txt tag config $tag -background $CFG([string toupper $tag]_BG)
@     $txt tag lower $tag
@   }
@   $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
@     -justify center
@   $txt tag config err -foreground $CFG(ERR_FG)
@ }
@ text .mkr
@
@ foreach c [cols] {
@   set keyPrefix [string toupper [colType $c]]_COL_
@   if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}}
@   $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
@     -padx $CFG(PADX) -yscroll sync-y
@   $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
@      -foreground $CFG(HR_FG)
@   $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
@   bindtags $c ". $c Text all"
@   bind $c <1> {focus %W}
@ }
@
@ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
@ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
@ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
@ frame .spacer
@
@ if {[readDiffs $fossilcmd] == 0} {
@   tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
@   exit
@ }
@ update idletasks
@
@ proc saveDiff {} {
@   set fn [tk_getSaveFile]
@   if {$fn==""} return
@   set out [open $fn wb]
@   puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
@   puts $out "# to see the graphical diff.\n#"
@   puts $out "set fossilcmd {}"
@   puts $out "set prog [list $::prog]"
@   puts $out "set difftxt \173"
@   foreach e $::difftxt {puts $out [list $e]}
@   puts $out "\175"
@   puts $out "eval \$prog"
@   close $out
@ }
@ proc invertDiff {} {
@   global CFG
@   array set x [grid info .txtA]
@   if {$x(-column)==1} {
@     grid config .lnB -column 0
@     grid config .txtB -column 1
@     .txtB tag config add -background $CFG(RM_BG)
@     grid config .lnA -column 3
@     grid config .txtA -column 4
@     .txtA tag config rm -background $CFG(ADD_BG)
@   } else {
@     grid config .lnA -column 0
@     grid config .txtA -column 1
@     .txtA tag config rm -background $CFG(RM_BG)
@     grid config .lnB -column 3
@     grid config .txtB -column 4
@     .txtB tag config add -background $CFG(ADD_BG)
@   }
@   .mkr config -state normal
@   set clt [.mkr search -all < 1.0 end]
@   set cgt [.mkr search -all > 1.0 end]
@   foreach c $clt {.mkr replace $c "$c +1 chars" >}
@   foreach c $cgt {.mkr replace $c "$c +1 chars" <}
@   .mkr config -state disabled
@ }
@ ::ttk::button .bb.quit -text {Quit} -command exit
@ ::ttk::button .bb.invert -text {Invert} -command invertDiff
@ ::ttk::button .bb.save -text {Save As...} -command saveDiff
@ pack .bb.quit .bb.invert -side left
@ if {$fossilcmd!=""} {pack .bb.save -side left}
@ pack .bb.files -side left
@ grid rowconfigure . 1 -weight 1
@ grid columnconfigure . 1 -weight 1
@ grid columnconfigure . 4 -weight 1
@ grid .bb -row 0 -columnspan 6
@ eval grid [cols] -row 1 -sticky nsew
@ grid .sby -row 1 -column 5 -sticky ns
@ grid .sbxA -row 2 -columnspan 2 -sticky ew
@ grid .spacer -row 2 -column 2
@ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew
@
@ .spacer config -height [winfo height .sbxA]
@ wm deiconify .
@ }
@ eval $prog
;

/*
** Show diff output in a Tcl/Tk window, in response to the --tk option
** to the diff command.
**
** If fossil has direct access to a Tcl interpreter (either loaded
** dynamically through stubs or linked in statically), we can use it
** directly. Otherwise:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







615
616
617
618
619
620
621


































































































































































































































































































































































































622
623
624
625
626
627
628
  }else{
    zDefault = 0;
    zName = "diff-command";
  }
  return db_get(zName, zDefault);
}



































































































































































































































































































































































































/*
** Show diff output in a Tcl/Tk window, in response to the --tk option
** to the diff command.
**
** If fossil has direct access to a Tcl interpreter (either loaded
** dynamically through stubs or linked in statically), we can use it
** directly. Otherwise:
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
      blob_appendf(&script, " {%/}", z);
    }else{
      int j;
      blob_append(&script, " ", 1);
      for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
    }
  }
  blob_appendf(&script, "}\n%s", zDiffScript);
  if( zTempFile ){
    blob_write_to_file(&script, zTempFile);
    fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
  }else{
#if defined(FOSSIL_ENABLE_TCL)
    Th_FossilInit(TH_INIT_DEFAULT);
    if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),







|







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
      blob_appendf(&script, " {%/}", z);
    }else{
      int j;
      blob_append(&script, " ", 1);
      for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
    }
  }
  blob_appendf(&script, "}\n%s", builtin_file("diff.tcl", 0));
  if( zTempFile ){
    blob_write_to_file(&script, zTempFile);
    fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
  }else{
#if defined(FOSSIL_ENABLE_TCL)
    Th_FossilInit(TH_INIT_DEFAULT);
    if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
Changes to src/doc.c.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

/*
** Try to guess the mimetype from content.
**
** If the content is pure text, return NULL.
**
** For image types, attempt to return an appropriate mimetype
** name like "image/gif" or "image/jpeg".  
**
** For any other binary type, return "unknown/unknown".
*/
const char *mimetype_from_content(Blob *pBlob){
  int i;
  int n;
  const unsigned char *x;







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

/*
** Try to guess the mimetype from content.
**
** If the content is pure text, return NULL.
**
** For image types, attempt to return an appropriate mimetype
** name like "image/gif" or "image/jpeg".
**
** For any other binary type, return "unknown/unknown".
*/
const char *mimetype_from_content(Blob *pBlob){
  int i;
  int n;
  const unsigned char *x;
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const char *mimetype_from_name(const char *zName){
  const char *z;
  int i;
  int first, last;
  int len;
  char zSuffix[20];

  /* A table of mimetypes based on file suffixes. 
  ** Suffixes must be in sorted order so that we can do a binary
  ** search to find the mime-type
  */
  static const struct {
    const char *zSuffix;       /* The file suffix */
    int size;                  /* Length of the suffix */
    const char *zMimetype;     /* The corresponding mimetype */







|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const char *mimetype_from_name(const char *zName){
  const char *z;
  int i;
  int first, last;
  int len;
  char zSuffix[20];

  /* A table of mimetypes based on file suffixes.
  ** Suffixes must be in sorted order so that we can do a binary
  ** search to find the mime-type
  */
  static const struct {
    const char *zSuffix;       /* The file suffix */
    int size;                  /* Length of the suffix */
    const char *zMimetype;     /* The corresponding mimetype */
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
      goto doc_not_found;
    }
    db_end_transaction(0);
  }
  blob_to_utf8_no_bom(&filebody, 0);

  /* The file is now contained in the filebody blob.  Deliver the
  ** file to the user 
  */
  zMime = P("mimetype");
  if( zMime==0 ){
    zMime = mimetype_from_name(zName);
  }
  Th_Store("doc_name", zName);
  Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
                                     "  FROM blob WHERE rid=%d", vid));
  Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
                                  " WHERE objid=%d AND type='ci'", vid));
  if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
    Blob title, tail;
    if( wiki_find_title(&filebody, &title, &tail) ){
      style_header(blob_str(&title));
      wiki_convert(&tail, 0, WIKI_BUTTONS);
    }else{
      style_header("Documentation");
      wiki_convert(&filebody, 0, WIKI_BUTTONS);
    }
    style_footer();
  }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
    Blob title = BLOB_INITIALIZER;
    Blob tail = BLOB_INITIALIZER;
    markdown_to_html(&filebody, &title, &tail);
    if( blob_size(&title)>0 ){
      style_header(blob_str(&title));
    }else{
      style_header("Documentation");
    }
    blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
    style_footer();
  }else if( fossil_strcmp(zMime, "text/plain")==0 ){
    style_header("Documentation");
    @ <blockquote><pre>
    @ %h(blob_str(&filebody))
    @ </pre></blockquote>
    style_footer();
#ifdef FOSSIL_ENABLE_TH1_DOCS
  }else if( db_get_boolean("th1-docs", 0) &&
            fossil_strcmp(zMime, "application/x-th1")==0 ){
    char *zHtml = htmlize(zName, -1);
    style_header(zHtml);
    Th_Render(blob_str(&filebody));
    style_footer();
    fossil_free(zHtml);
#endif
  }else{
    cgi_set_content_type(zMime);
    cgi_set_content(&filebody);
  }
  return;

doc_not_found:
  /* Jump here when unable to locate the document */
  db_end_transaction(0);
  style_header("Document Not Found");
  @ <p>No such document: %h(zName)</p>
  style_footer();
  return;  
}

/*
** The default logo.
*/
static const unsigned char aLogo[] = {
    71,  73,  70,  56,  55,  97,  62,   0,  71,   0, 244,   0,   0,  85, 
   129, 149,  95, 136, 155,  99, 139, 157, 106, 144, 162, 113, 150, 166, 
   116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184, 
   195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201, 
   215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237, 
   233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255,   0,   0, 
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  44,   0,   0, 
     0,   0,  62,   0,  71,   0,   0,   5, 255,  96, 100, 141, 100, 105, 
   158, 168,  37,  41, 132, 192, 164, 112,  44, 207, 102,  99,   0,  56, 
    16,  84, 116, 239, 199, 141,  65, 110, 232, 248,  25, 141, 193, 161, 
    82, 113, 108, 202,  32,  55, 229, 210,  73,  61,  41, 164,  88, 102, 
   181,  10,  41,  96, 179,  91, 106,  35, 240,   5, 135, 143, 137, 242, 
    87, 123, 246,  33, 190,  81, 108, 163, 237, 198,  14,  30, 113, 233, 
   131,  78, 115,  72,  11, 115,  87, 101,  19, 124,  51,  66,  74,   8, 
    19,  16,  67, 100,  74, 133,  50,  15, 101, 135,  56,  11,  74,   6, 
   143,  49, 126, 106,  56,   8, 145,  67,   9, 152,  48, 139, 155,   5, 
    22,  13,  74, 115, 161,  41, 147, 101,  13, 130,  57, 132, 170,  40, 
   167, 155,   0,  94,  57,   3, 178,  48, 183, 181,  57, 160, 186,  40, 
    19, 141, 189,   0,  69, 192,  40,  16, 195, 155, 185, 199,  41, 201, 
   189, 191, 205, 193, 188, 131, 210,  49, 175,  88, 209, 214,  38,  19, 
     3,  11,  19, 111, 127,  60, 219,  39,  55, 204,  19,  11,   6, 100, 
     5,  10, 227, 228,  37, 163,   0, 239, 117,  56, 238, 243,  49, 195, 
   177, 247,  48, 158,  56, 251,  50, 216, 254, 197,  56, 128, 107, 158, 
     2, 125, 171, 114,  92, 218, 246,  96,  66,   3,   4,  50, 134, 176, 
   145,   6,  97,  64, 144,  24,  19, 136, 108,  91, 177, 160,   0, 194, 
    19, 253,   0, 216, 107, 214, 224, 192, 129,   5,  16,  83, 255, 244, 
    43, 213, 195,  24, 159,  27, 169,  64, 230,  88, 208, 227, 129, 182, 
    54,   4,  89, 158,  24, 181, 163, 199,   1, 155,  52, 233,   8, 130, 
   176,  83,  24, 128, 137,  50,  18,  32,  48,  48, 114,  11, 173, 137, 
    19, 110,   4,  64, 105,   1, 194,  30, 140,  68,  15,  24,  24, 224, 
    50,  76,  70,   0,  11, 171,  54,  26, 160, 181, 194, 149, 148,  40, 
   174, 148, 122,  64, 180, 208, 161,  17, 207, 112, 164,   1, 128,  96, 
   148,  78,  18,  21, 194,  33, 229,  51, 247,  65, 133,  97,   5, 250, 
    69, 229, 100,  34, 220, 128, 166, 116, 190,  62,   8, 167, 195, 170, 
    47, 163,   0, 130,  90, 152,  11, 160, 173, 170,  27, 154,  26,  91, 
   232, 151, 171,  18,  14, 162, 253,  98, 170,  18,  70, 171,  64, 219, 
    10,  67, 136, 134, 187, 116,  75, 180,  46, 179, 174, 135,   4, 189, 
   229, 231,  78,  40,  10,  62, 226, 164, 172,  64, 240, 167, 170,  10, 
    18, 124, 188,  10, 107,  65, 193,  94,  11,  93, 171,  28, 248,  17, 
   239,  46, 140,  78,  97,  34,  25, 153,  36,  99,  65, 130,   7, 203, 
   183, 168,  51,  34, 136,  25, 140,  10,   6,  16,  28, 255, 145, 241, 
   230, 140,  10,  66, 178, 167, 112,  48, 192, 128, 129,   9,  31, 141, 
    84, 138,  63, 163, 162,   2, 203, 206, 240,  56,  55,  98, 192, 188, 
    15, 185,  50, 160,   6,   0, 125,  62,  33, 214, 195,  33,   5,  24, 
   184,  25, 231,  14, 201, 245, 144,  23, 126, 104, 228,   0, 145,   2, 
    13, 140, 244, 212,  17,  21,  20, 176, 159,  17,  95, 225, 160, 128, 
    16,   1,  32, 224, 142,  32, 227, 125,  87,  64,   0,  16,  54, 129, 
   205,   2, 141,  76,  53, 130, 103,  37, 166,  64, 144, 107,  78, 196, 
     5, 192,   0,  54,  50, 229,   9, 141,  49,  84, 194,  35,  12, 196, 
   153,  48, 192, 137,  57,  84,  24,   7,  87, 159, 249, 240, 215, 143, 
   105, 241, 118, 149,   9, 139,   4,  64, 203, 141,  35, 140, 129, 131, 
    16, 222, 125, 231, 128,   2, 238,  17, 152,  66,   3,   5,  56, 224, 
   159, 103,  16,  76,  25,  75,   5,  11, 164, 215,  96,   9,  14,  16, 
    36, 225,  15,  11,  40, 144, 192, 156,  41,  10, 178, 199,   3,  66, 
    64,  80, 193,   3, 124,  90,  48, 129, 129, 102, 177,  18, 192, 154, 
    49,  84, 240, 208,  92,  22, 149,  96,  39,   9,  31,  74,  17,  94, 
     3,   8, 177, 199,  72,  59,  85,  76,  25, 216,   8, 139, 194, 197, 
   138, 163,  69,  96, 115,   0, 147,  72,  72,  84,  28,  14,  79,  86, 
   233, 230,  23, 113,  26, 160, 128,   3,  10,  58, 129, 103,  14, 159, 
   214, 163, 146, 117, 238, 213, 154, 128, 151, 109,  84,  64, 217,  13, 
    27,  10, 228,  39,   2, 235, 164, 168,  74,   8,   0,  59, 
};

/*
** WEBPAGE: logo
**
** Return the logo image.  This image is available to anybody who can see
** the login page.  It is designed for use in the upper left-hand corner







|













|











|














<
|


<













|






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

533
534
535

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
      goto doc_not_found;
    }
    db_end_transaction(0);
  }
  blob_to_utf8_no_bom(&filebody, 0);

  /* The file is now contained in the filebody blob.  Deliver the
  ** file to the user
  */
  zMime = P("mimetype");
  if( zMime==0 ){
    zMime = mimetype_from_name(zName);
  }
  Th_Store("doc_name", zName);
  Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
                                     "  FROM blob WHERE rid=%d", vid));
  Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
                                  " WHERE objid=%d AND type='ci'", vid));
  if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
    Blob title, tail;
    if( wiki_find_title(&filebody, &title, &tail) ){
      style_header("%s", blob_str(&title));
      wiki_convert(&tail, 0, WIKI_BUTTONS);
    }else{
      style_header("Documentation");
      wiki_convert(&filebody, 0, WIKI_BUTTONS);
    }
    style_footer();
  }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
    Blob title = BLOB_INITIALIZER;
    Blob tail = BLOB_INITIALIZER;
    markdown_to_html(&filebody, &title, &tail);
    if( blob_size(&title)>0 ){
      style_header("%s", blob_str(&title));
    }else{
      style_header("Documentation");
    }
    blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
    style_footer();
  }else if( fossil_strcmp(zMime, "text/plain")==0 ){
    style_header("Documentation");
    @ <blockquote><pre>
    @ %h(blob_str(&filebody))
    @ </pre></blockquote>
    style_footer();
#ifdef FOSSIL_ENABLE_TH1_DOCS
  }else if( db_get_boolean("th1-docs", 0) &&
            fossil_strcmp(zMime, "application/x-th1")==0 ){

    style_header("%h", zName);
    Th_Render(blob_str(&filebody));
    style_footer();

#endif
  }else{
    cgi_set_content_type(zMime);
    cgi_set_content(&filebody);
  }
  return;

doc_not_found:
  /* Jump here when unable to locate the document */
  db_end_transaction(0);
  style_header("Document Not Found");
  @ <p>No such document: %h(zName)</p>
  style_footer();
  return;
}

/*
** The default logo.
*/
static const unsigned char aLogo[] = {
    71,  73,  70,  56,  55,  97,  62,   0,  71,   0, 244,   0,   0,  85,
   129, 149,  95, 136, 155,  99, 139, 157, 106, 144, 162, 113, 150, 166,
   116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
   195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
   215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
   233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255,   0,   0,
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  44,   0,   0,
     0,   0,  62,   0,  71,   0,   0,   5, 255,  96, 100, 141, 100, 105,
   158, 168,  37,  41, 132, 192, 164, 112,  44, 207, 102,  99,   0,  56,
    16,  84, 116, 239, 199, 141,  65, 110, 232, 248,  25, 141, 193, 161,
    82, 113, 108, 202,  32,  55, 229, 210,  73,  61,  41, 164,  88, 102,
   181,  10,  41,  96, 179,  91, 106,  35, 240,   5, 135, 143, 137, 242,
    87, 123, 246,  33, 190,  81, 108, 163, 237, 198,  14,  30, 113, 233,
   131,  78, 115,  72,  11, 115,  87, 101,  19, 124,  51,  66,  74,   8,
    19,  16,  67, 100,  74, 133,  50,  15, 101, 135,  56,  11,  74,   6,
   143,  49, 126, 106,  56,   8, 145,  67,   9, 152,  48, 139, 155,   5,
    22,  13,  74, 115, 161,  41, 147, 101,  13, 130,  57, 132, 170,  40,
   167, 155,   0,  94,  57,   3, 178,  48, 183, 181,  57, 160, 186,  40,
    19, 141, 189,   0,  69, 192,  40,  16, 195, 155, 185, 199,  41, 201,
   189, 191, 205, 193, 188, 131, 210,  49, 175,  88, 209, 214,  38,  19,
     3,  11,  19, 111, 127,  60, 219,  39,  55, 204,  19,  11,   6, 100,
     5,  10, 227, 228,  37, 163,   0, 239, 117,  56, 238, 243,  49, 195,
   177, 247,  48, 158,  56, 251,  50, 216, 254, 197,  56, 128, 107, 158,
     2, 125, 171, 114,  92, 218, 246,  96,  66,   3,   4,  50, 134, 176,
   145,   6,  97,  64, 144,  24,  19, 136, 108,  91, 177, 160,   0, 194,
    19, 253,   0, 216, 107, 214, 224, 192, 129,   5,  16,  83, 255, 244,
    43, 213, 195,  24, 159,  27, 169,  64, 230,  88, 208, 227, 129, 182,
    54,   4,  89, 158,  24, 181, 163, 199,   1, 155,  52, 233,   8, 130,
   176,  83,  24, 128, 137,  50,  18,  32,  48,  48, 114,  11, 173, 137,
    19, 110,   4,  64, 105,   1, 194,  30, 140,  68,  15,  24,  24, 224,
    50,  76,  70,   0,  11, 171,  54,  26, 160, 181, 194, 149, 148,  40,
   174, 148, 122,  64, 180, 208, 161,  17, 207, 112, 164,   1, 128,  96,
   148,  78,  18,  21, 194,  33, 229,  51, 247,  65, 133,  97,   5, 250,
    69, 229, 100,  34, 220, 128, 166, 116, 190,  62,   8, 167, 195, 170,
    47, 163,   0, 130,  90, 152,  11, 160, 173, 170,  27, 154,  26,  91,
   232, 151, 171,  18,  14, 162, 253,  98, 170,  18,  70, 171,  64, 219,
    10,  67, 136, 134, 187, 116,  75, 180,  46, 179, 174, 135,   4, 189,
   229, 231,  78,  40,  10,  62, 226, 164, 172,  64, 240, 167, 170,  10,
    18, 124, 188,  10, 107,  65, 193,  94,  11,  93, 171,  28, 248,  17,
   239,  46, 140,  78,  97,  34,  25, 153,  36,  99,  65, 130,   7, 203,
   183, 168,  51,  34, 136,  25, 140,  10,   6,  16,  28, 255, 145, 241,
   230, 140,  10,  66, 178, 167, 112,  48, 192, 128, 129,   9,  31, 141,
    84, 138,  63, 163, 162,   2, 203, 206, 240,  56,  55,  98, 192, 188,
    15, 185,  50, 160,   6,   0, 125,  62,  33, 214, 195,  33,   5,  24,
   184,  25, 231,  14, 201, 245, 144,  23, 126, 104, 228,   0, 145,   2,
    13, 140, 244, 212,  17,  21,  20, 176, 159,  17,  95, 225, 160, 128,
    16,   1,  32, 224, 142,  32, 227, 125,  87,  64,   0,  16,  54, 129,
   205,   2, 141,  76,  53, 130, 103,  37, 166,  64, 144, 107,  78, 196,
     5, 192,   0,  54,  50, 229,   9, 141,  49,  84, 194,  35,  12, 196,
   153,  48, 192, 137,  57,  84,  24,   7,  87, 159, 249, 240, 215, 143,
   105, 241, 118, 149,   9, 139,   4,  64, 203, 141,  35, 140, 129, 131,
    16, 222, 125, 231, 128,   2, 238,  17, 152,  66,   3,   5,  56, 224,
   159, 103,  16,  76,  25,  75,   5,  11, 164, 215,  96,   9,  14,  16,
    36, 225,  15,  11,  40, 144, 192, 156,  41,  10, 178, 199,   3,  66,
    64,  80, 193,   3, 124,  90,  48, 129, 129, 102, 177,  18, 192, 154,
    49,  84, 240, 208,  92,  22, 149,  96,  39,   9,  31,  74,  17,  94,
     3,   8, 177, 199,  72,  59,  85,  76,  25, 216,   8, 139, 194, 197,
   138, 163,  69,  96, 115,   0, 147,  72,  72,  84,  28,  14,  79,  86,
   233, 230,  23, 113,  26, 160, 128,   3,  10,  58, 129, 103,  14, 159,
   214, 163, 146, 117, 238, 213, 154, 128, 151, 109,  84,  64, 217,  13,
    27,  10, 228,  39,   2, 235, 164, 168,  74,   8,   0,  59,
};

/*
** WEBPAGE: logo
**
** Return the logo image.  This image is available to anybody who can see
** the login page.  It is designed for use in the upper left-hand corner
Changes to src/encode.c.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    }
    i++;
  }
  i = 0;
  zOut = fossil_malloc( count+1 );
  while( n-->0 && (c = *zIn)!=0 ){
    switch( c ){
      case '<':   
        zOut[i++] = '&';
        zOut[i++] = 'l';
        zOut[i++] = 't';
        zOut[i++] = ';';
        break;
      case '>':   
        zOut[i++] = '&';
        zOut[i++] = 'g';
        zOut[i++] = 't';
        zOut[i++] = ';';
        break;
      case '&':   
        zOut[i++] = '&';
        zOut[i++] = 'a';
        zOut[i++] = 'm';
        zOut[i++] = 'p';
        zOut[i++] = ';';
        break;
      case '"':   
        zOut[i++] = '&';
        zOut[i++] = 'q';
        zOut[i++] = 'u';
        zOut[i++] = 'o';
        zOut[i++] = 't';
        zOut[i++] = ';';
        break;







|





|





|






|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    }
    i++;
  }
  i = 0;
  zOut = fossil_malloc( count+1 );
  while( n-->0 && (c = *zIn)!=0 ){
    switch( c ){
      case '<':
        zOut[i++] = '&';
        zOut[i++] = 'l';
        zOut[i++] = 't';
        zOut[i++] = ';';
        break;
      case '>':
        zOut[i++] = '&';
        zOut[i++] = 'g';
        zOut[i++] = 't';
        zOut[i++] = ';';
        break;
      case '&':
        zOut[i++] = '&';
        zOut[i++] = 'a';
        zOut[i++] = 'm';
        zOut[i++] = 'p';
        zOut[i++] = ';';
        break;
      case '"':
        zOut[i++] = '&';
        zOut[i++] = 'q';
        zOut[i++] = 'u';
        zOut[i++] = 'o';
        zOut[i++] = 't';
        zOut[i++] = ';';
        break;
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
}

/*
** Convert the input string into a form that is suitable for use as
** a token in the HTTP protocol.  Spaces are encoded as '+' and special
** characters are encoded as "%HH" where HH is a two-digit hexidecimal
** representation of the character.  The "/" character is not encoded
** by this routine. 
*/
char *urlize(const char *z, int n){
  return EncodeHttp(z, n, 0);
}

/*
** Convert a single HEX digit to an integer







|







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
}

/*
** Convert the input string into a form that is suitable for use as
** a token in the HTTP protocol.  Spaces are encoded as '+' and special
** characters are encoded as "%HH" where HH is a two-digit hexidecimal
** representation of the character.  The "/" character is not encoded
** by this routine.
*/
char *urlize(const char *z, int n){
  return EncodeHttp(z, n, 0);
}

/*
** Convert a single HEX digit to an integer
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  if( z[j] ) z[j] = 0;
}


/*
** The characters used for HTTP base64 encoding.
*/
static unsigned char zBase[] = 
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/*
** Encode a string using a base-64 encoding.
** The encoding can be reversed using the <b>decode64</b> function.
**
** Space to hold the result comes from malloc().







|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  if( z[j] ) z[j] = 0;
}


/*
** The characters used for HTTP base64 encoding.
*/
static unsigned char zBase[] =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/*
** Encode a string using a base-64 encoding.
** The encoding can be reversed using the <b>decode64</b> function.
**
** Space to hold the result comes from malloc().
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    z64[n++] = '=';
  }
  z64[n] = 0;
  return z64;
}

/*
** COMMAND: test-encode64 
** Usage: %fossil test-encode64 STRING
*/
void test_encode64_cmd(void){
  char *z;
  int i;
  for(i=2; i<g.argc; i++){
    z = encode64(g.argv[i], -1);







|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    z64[n++] = '=';
  }
  z64[n] = 0;
  return z64;
}

/*
** COMMAND: test-encode64
** Usage: %fossil test-encode64 STRING
*/
void test_encode64_cmd(void){
  char *z;
  int i;
  for(i=2; i<g.argc; i++){
    z = encode64(g.argv[i], -1);
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
  }
  zData[j] = 0;
  *pnByte = j;
  return zData;
}

/*
** COMMAND: test-decode64 
** Usage: %fossil test-decode64 STRING
*/
void test_decode64_cmd(void){
  char *z;
  int i, n;
  for(i=2; i<g.argc; i++){
    z = decode64(g.argv[i], &n);







|







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
  }
  zData[j] = 0;
  *pnByte = j;
  return zData;
}

/*
** COMMAND: test-decode64
** Usage: %fossil test-decode64 STRING
*/
void test_decode64_cmd(void){
  char *z;
  int i, n;
  for(i=2; i<g.argc; i++){
    z = decode64(g.argv[i], &n);
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
**         0123456789abcdef
**
*/

/*
** The array used for encoding
*/                           /* 123456789 12345  */
static const char zEncode[] = "0123456789abcdef"; 

/*
** Encode a N-digit base-256 in base-16.  Return zero on success
** and non-zero if there is an error.
*/
int encode16(const unsigned char *pIn, unsigned char *zOut, int N){
  int i;
  for(i=0; i<N; i++){
    *(zOut++) = zEncode[pIn[i]>>4];
    *(zOut++) = zEncode[pIn[i]&0xf];
  }
  *zOut = 0;
  return 0;
}

/*
** An array for translating single base-16 characters into a value.
** Disallowed input characters have a value of 64.  Upper and lower
** case is the same. 
*/
static const char zDecode[] = {
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
   0,  1,  2,  3,  4,  5,  6,  7,   8,  9, 64, 64, 64, 64, 64, 64, 
  64, 10, 11, 12, 13, 14, 15, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 10, 11, 12, 13, 14, 15, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 
};

/*
** Decode a N-character base-16 number into base-256.  N must be a 
** multiple of 2.  The output buffer must be at least N/2 characters
** in length
*/
int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
  int i, j;
  if( (N&1)!=0 ) return 1;
  for(i=j=0; i<N; i += 2, j++){







|


















|


|
|
|
|




|
|
|
|
|
|
|
|



|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
**         0123456789abcdef
**
*/

/*
** The array used for encoding
*/                           /* 123456789 12345  */
static const char zEncode[] = "0123456789abcdef";

/*
** Encode a N-digit base-256 in base-16.  Return zero on success
** and non-zero if there is an error.
*/
int encode16(const unsigned char *pIn, unsigned char *zOut, int N){
  int i;
  for(i=0; i<N; i++){
    *(zOut++) = zEncode[pIn[i]>>4];
    *(zOut++) = zEncode[pIn[i]&0xf];
  }
  *zOut = 0;
  return 0;
}

/*
** An array for translating single base-16 characters into a value.
** Disallowed input characters have a value of 64.  Upper and lower
** case is the same.
*/
static const char zDecode[] = {
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
   0,  1,  2,  3,  4,  5,  6,  7,   8,  9, 64, 64, 64, 64, 64, 64,
  64, 10, 11, 12, 13, 14, 15, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 10, 11, 12, 13, 14, 15, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
  64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
};

/*
** Decode a N-character base-16 number into base-256.  N must be a
** multiple of 2.  The output buffer must be at least N/2 characters
** in length
*/
int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
  int i, j;
  if( (N&1)!=0 ) return 1;
  for(i=j=0; i<N; i += 2, j++){
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
}

/* Randomness used for XOR-ing by the obscure() and unobscure() routines */
static const unsigned char aObscurer[16] = {
    0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
    0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
};
 

/*
** Obscure plain text so that it is not easily readable.
**
** This is used for storing sensitive information (such as passwords) in a
** way that prevents their exposure through idle browsing.  This is not
** encryption.  Anybody who really wants the password can still get it.
**
** The text is XOR-ed with a repeating pattern then converted to hex.
** Space to hold the returned string is obtained from malloc and should
** be freed by the caller.
*/
char *obscure(const char *zIn){
  int n, i;
  unsigned char salt;
  char *zOut;
  
  if( zIn==0 ) return 0;
  n = strlen(zIn);
  zOut = fossil_malloc( n*2+3 );
  sqlite3_randomness(1, &salt);
  zOut[n+1] = (char)salt;
  for(i=0; i<n; i++) zOut[i+n+2] = zIn[i]^aObscurer[i&0x0f]^salt;
  encode16((unsigned char*)&zOut[n+1], (unsigned char*)zOut, n+1);
  return zOut;
}

/*
** Undo the obscuring of text performed by obscure().  Or, if the input is
** not hexadecimal (meaning the input is not the output of obscure()) then
** do the equivalent of strdup().
**
** The result is memory obtained from malloc that should be freed by the caller. 
*/
char *unobscure(const char *zIn){
  int n, i;
  unsigned char salt;
  char *zOut;
  
  if( zIn==0 ) return 0;
  n = strlen(zIn);
  zOut = fossil_malloc( n + 1 );
  if( n<2
    || decode16((unsigned char*)zIn, &salt, 2)
    || decode16((unsigned char*)&zIn[2], (unsigned char*)zOut, n-2)
  ){







|
















|















|





|







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
}

/* Randomness used for XOR-ing by the obscure() and unobscure() routines */
static const unsigned char aObscurer[16] = {
    0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
    0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
};


/*
** Obscure plain text so that it is not easily readable.
**
** This is used for storing sensitive information (such as passwords) in a
** way that prevents their exposure through idle browsing.  This is not
** encryption.  Anybody who really wants the password can still get it.
**
** The text is XOR-ed with a repeating pattern then converted to hex.
** Space to hold the returned string is obtained from malloc and should
** be freed by the caller.
*/
char *obscure(const char *zIn){
  int n, i;
  unsigned char salt;
  char *zOut;

  if( zIn==0 ) return 0;
  n = strlen(zIn);
  zOut = fossil_malloc( n*2+3 );
  sqlite3_randomness(1, &salt);
  zOut[n+1] = (char)salt;
  for(i=0; i<n; i++) zOut[i+n+2] = zIn[i]^aObscurer[i&0x0f]^salt;
  encode16((unsigned char*)&zOut[n+1], (unsigned char*)zOut, n+1);
  return zOut;
}

/*
** Undo the obscuring of text performed by obscure().  Or, if the input is
** not hexadecimal (meaning the input is not the output of obscure()) then
** do the equivalent of strdup().
**
** The result is memory obtained from malloc that should be freed by the caller.
*/
char *unobscure(const char *zIn){
  int n, i;
  unsigned char salt;
  char *zOut;

  if( zIn==0 ) return 0;
  n = strlen(zIn);
  zOut = fossil_malloc( n + 1 );
  if( n<2
    || decode16((unsigned char*)zIn, &salt, 2)
    || decode16((unsigned char*)&zIn[2], (unsigned char*)zOut, n-2)
  ){
Changes to src/event.c.
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  */
  pEvent = manifest_get(rid, CFTYPE_EVENT, 0);
  if( pEvent==0 ){
    fossil_fatal("Object #%d is not an event", rid);
  }
  blob_init(&fullbody, pEvent->zWiki, -1);
  if( wiki_find_title(&fullbody, &title, &tail) ){
    style_header(blob_str(&title));
  }else{
    style_header("Event %S", zEventId);
    tail = fullbody;
  }
  if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
    style_submenu_element("Edit", "Edit", "%s/eventedit?name=%s",
                          g.zTop, zEventId);







|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  */
  pEvent = manifest_get(rid, CFTYPE_EVENT, 0);
  if( pEvent==0 ){
    fossil_fatal("Object #%d is not an event", rid);
  }
  blob_init(&fullbody, pEvent->zWiki, -1);
  if( wiki_find_title(&fullbody, &title, &tail) ){
    style_header("%s", blob_str(&title));
  }else{
    style_header("Event %S", zEventId);
    tail = fullbody;
  }
  if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
    style_submenu_element("Edit", "Edit", "%s/eventedit?name=%s",
                          g.zTop, zEventId);
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
** Edit an event.  If name is omitted, create a new event.
*/
void eventedit_page(void){
  char *zTag;
  int rid = 0;
  Blob event;
  const char *zEventId;
  char *zHtmlPageName;
  int n;
  const char *z;
  char *zBody = (char*)P("w");
  char *zETime = (char*)P("t");
  const char *zComment = P("c");
  const char *zTags = P("g");
  const char *zClr;







<







201
202
203
204
205
206
207

208
209
210
211
212
213
214
** Edit an event.  If name is omitted, create a new event.
*/
void eventedit_page(void){
  char *zTag;
  int rid = 0;
  Blob event;
  const char *zEventId;

  int n;
  const char *z;
  char *zBody = (char*)P("w");
  char *zETime = (char*)P("t");
  const char *zComment = P("c");
  const char *zTags = P("g");
  const char *zClr;
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
  if( P("cancel")!=0 ){
    cgi_redirectf("event?name=%T", zEventId);
    return;
  }
  if( zBody==0 ){
    zBody = mprintf("<i>Event Text</i>");
  }
  zHtmlPageName = mprintf("Edit Event %S", zEventId);
  style_header(zHtmlPageName);
  if( P("preview")!=0 ){
    Blob title, tail, com;
    @ <p><b>Timeline comment preview:</b></p>
    @ <blockquote>
    @ <table border="0">
    if( zClr && zClr[0] ){
      @ <tr><td style="background-color: %h(zClr);">







|
<







361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
  if( P("cancel")!=0 ){
    cgi_redirectf("event?name=%T", zEventId);
    return;
  }
  if( zBody==0 ){
    zBody = mprintf("<i>Event Text</i>");
  }
  style_header("Edit Event %S", zEventId);

  if( P("preview")!=0 ){
    Blob title, tail, com;
    @ <p><b>Timeline comment preview:</b></p>
    @ <blockquote>
    @ <table border="0">
    if( zClr && zClr[0] ){
      @ <tr><td style="background-color: %h(zClr);">
Changes to src/export.c.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  }
  if( zContact[i]=='<' ){
    /*
    ** Found beginning of email address. Look for the end and extract
    ** the part.
     */
    zEmail = mprintf("%s", &zContact[i]);
    for(i=0; zEmail[i] && zEmail[i]!='>'; i++){}
    if( zEmail[i]=='>' ) zEmail[i+1] = 0;
  }else{
    /*
    ** Found an end marker for email, but nothing else.
     */
    zEmail = mprintf("<%s>", zUser);
  }
  /*







|
|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  }
  if( zContact[i]=='<' ){
    /*
    ** Found beginning of email address. Look for the end and extract
    ** the part.
     */
    zEmail = mprintf("%s", &zContact[i]);
    for(j=0; zEmail[j] && zEmail[j]!='>'; j++){}
    if( zEmail[j]=='>' ) zEmail[j+1] = 0;
  }else{
    /*
    ** Found an end marker for email, but nothing else.
     */
    zEmail = mprintf("<%s>", zUser);
  }
  /*
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  db_finalize(&q);
  db_finalize(&q2);
  db_finalize(&q3);

  /* Output the commit records.
  */
  db_prepare(&q,
    "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment),"
    "       coalesce(user,euser),"
    "       (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)"
    "  FROM event"
    " WHERE type='ci' AND NOT EXISTS (SELECT 1 FROM oldcommit WHERE objid=rid)"
    " ORDER BY mtime ASC",
    TAG_BRANCH
  );
  db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)");







|
|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  db_finalize(&q);
  db_finalize(&q2);
  db_finalize(&q3);

  /* Output the commit records.
  */
  db_prepare(&q,
    "SELECT strftime('%%s',mtime), objid, coalesce(ecomment,comment),"
    "       coalesce(euser,user),"
    "       (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)"
    "  FROM event"
    " WHERE type='ci' AND NOT EXISTS (SELECT 1 FROM oldcommit WHERE objid=rid)"
    " ORDER BY mtime ASC",
    TAG_BRANCH
  );
  db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)");
Changes to src/finfo.c.
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
  if( baseCheckin ) firstChngOnly = 1;
  if( !firstChngOnly ) url_add_parameter(&url, "fco", "0");

  zPrevDate[0] = 0;
  zFilename = PD("name","");
  url_add_parameter(&url, "name", zFilename);
  blob_zero(&sql);
  blob_appendf(&sql,
    "SELECT"
    " datetime(event.mtime%s),"                      /* Date of change */
    " coalesce(event.ecomment, event.comment),"      /* Check-in comment */
    " coalesce(event.euser, event.user),"            /* User who made chng */
    " mlink.pid,"                                    /* Parent file rid */
    " mlink.fid,"                                    /* File rid */
    " (SELECT uuid FROM blob WHERE rid=mlink.pid),"  /* Parent file uuid */
    " (SELECT uuid FROM blob WHERE rid=mlink.fid),"  /* Current file uuid */
    " (SELECT uuid FROM blob WHERE rid=mlink.mid),"  /* Check-in uuid */
    " event.bgcolor,"                                /* Background color */
    " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
                                " AND tagxref.rid=mlink.mid)," /* Tags */
    " mlink.mid,"                                    /* check-in ID */
    " mlink.pfnid",                                  /* Previous filename */
    timeline_utc(), TAG_BRANCH
  );
  if( firstChngOnly ){
#if 0
    blob_appendf(&sql, ", min(event.mtime)");
#else
    blob_appendf(&sql,
        ", min(CASE (SELECT value FROM tagxref"
                    " WHERE tagtype>0 AND tagid=%d"
                    "   AND tagxref.rid=mlink.mid)"
             " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
    TAG_BRANCH);
#endif
  }
  blob_appendf(&sql,
    "  FROM mlink, event"
    " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
    "   AND event.objid=mlink.mid",
    zFilename
  );
  if( baseCheckin ){
    compute_direct_ancestors(baseCheckin, 10000000);
    blob_appendf(&sql,"  AND mlink.mid IN (SELECT rid FROM ancestor)");
  }
  if( (zA = P("a"))!=0 ){
    blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
    url_add_parameter(&url, "a", zA);
  }
  if( (zB = P("b"))!=0 ){
    blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB);
    url_add_parameter(&url, "b", zB);
  }
  if( firstChngOnly ){
    blob_appendf(&sql, " GROUP BY mlink.fid");
  }
  blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/");
  if( (n = atoi(PD("n","0")))>0 ){
    blob_appendf(&sql, " LIMIT %d", n);
    url_add_parameter(&url, "n", P("n"));
  }
  if( baseCheckin==0 ){
    if( firstChngOnly ){
      style_submenu_element("Full", "Show all changes","%s",
                            url_render(&url, "fco", "0", 0, 0));
    }else{
      style_submenu_element("Simplified",
                            "Show only first use of a change","%s",
                            url_render(&url, "fco", 0, 0, 0));
    }
  }
  db_prepare(&q, blob_str(&sql));
  if( P("showsql")!=0 ){
    @ <p>SQL: %h(blob_str(&sql))</p>
  }
  blob_reset(&sql);
  blob_zero(&title);
  if( baseCheckin ){
    char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin);







|


















|

|







|







|


|



|



|

|

|












|







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
  if( baseCheckin ) firstChngOnly = 1;
  if( !firstChngOnly ) url_add_parameter(&url, "fco", "0");

  zPrevDate[0] = 0;
  zFilename = PD("name","");
  url_add_parameter(&url, "name", zFilename);
  blob_zero(&sql);
  blob_append_sql(&sql,
    "SELECT"
    " datetime(event.mtime%s),"                      /* Date of change */
    " coalesce(event.ecomment, event.comment),"      /* Check-in comment */
    " coalesce(event.euser, event.user),"            /* User who made chng */
    " mlink.pid,"                                    /* Parent file rid */
    " mlink.fid,"                                    /* File rid */
    " (SELECT uuid FROM blob WHERE rid=mlink.pid),"  /* Parent file uuid */
    " (SELECT uuid FROM blob WHERE rid=mlink.fid),"  /* Current file uuid */
    " (SELECT uuid FROM blob WHERE rid=mlink.mid),"  /* Check-in uuid */
    " event.bgcolor,"                                /* Background color */
    " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
                                " AND tagxref.rid=mlink.mid)," /* Tags */
    " mlink.mid,"                                    /* check-in ID */
    " mlink.pfnid",                                  /* Previous filename */
    timeline_utc(), TAG_BRANCH
  );
  if( firstChngOnly ){
#if 0
    blob_append_sql(&sql, ", min(event.mtime)");
#else
    blob_append_sql(&sql,
        ", min(CASE (SELECT value FROM tagxref"
                    " WHERE tagtype>0 AND tagid=%d"
                    "   AND tagxref.rid=mlink.mid)"
             " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
    TAG_BRANCH);
#endif
  }
  blob_append_sql(&sql,
    "  FROM mlink, event"
    " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
    "   AND event.objid=mlink.mid",
    zFilename
  );
  if( baseCheckin ){
    compute_direct_ancestors(baseCheckin, 10000000);
    blob_append_sql(&sql,"  AND mlink.mid IN (SELECT rid FROM ancestor)");
  }
  if( (zA = P("a"))!=0 ){
    blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA);
    url_add_parameter(&url, "a", zA);
  }
  if( (zB = P("b"))!=0 ){
    blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
    url_add_parameter(&url, "b", zB);
  }
  if( firstChngOnly ){
    blob_append_sql(&sql, " GROUP BY mlink.fid");
  }
  blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/");
  if( (n = atoi(PD("n","0")))>0 ){
    blob_append_sql(&sql, " LIMIT %d", n);
    url_add_parameter(&url, "n", P("n"));
  }
  if( baseCheckin==0 ){
    if( firstChngOnly ){
      style_submenu_element("Full", "Show all changes","%s",
                            url_render(&url, "fco", "0", 0, 0));
    }else{
      style_submenu_element("Simplified",
                            "Show only first use of a change","%s",
                            url_render(&url, "fco", 0, 0, 0));
    }
  }
  db_prepare(&q, "%s", blob_sql_text(&sql));
  if( P("showsql")!=0 ){
    @ <p>SQL: %h(blob_str(&sql))</p>
  }
  blob_reset(&sql);
  blob_zero(&title);
  if( baseCheckin ){
    char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin);
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
        @ %z(href("%R/finfo?name=%t",zNewName))%h(zNewName)</a> by check-in
        fossil_free(zNewName);
      }else{
        @ <b>Deleted</b> by check-in
      }
    }
    hyperlink_to_uuid(zCkin);
    @ %w(zCom) (user:
    hyperlink_to_user(zUser, zDate, "");
    @ branch: %h(zBr))
    if( g.perm.Hyperlink && zUuid ){
      const char *z = zFilename;
      @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
      @ [annotate]</a>
      @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))







|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
        @ %z(href("%R/finfo?name=%t",zNewName))%h(zNewName)</a> by check-in
        fossil_free(zNewName);
      }else{
        @ <b>Deleted</b> by check-in
      }
    }
    hyperlink_to_uuid(zCkin);
    @ %W(zCom) (user:
    hyperlink_to_user(zUser, zDate, "");
    @ branch: %h(zBr))
    if( g.perm.Hyperlink && zUuid ){
      const char *z = zFilename;
      @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
      @ [annotate]</a>
      @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))
Changes to src/http.c.
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  char *zUser;
  char *zPw;
  char *zPrompt;
  char *zHttpAuth = 0;
  if( !isatty(fileno(stdin)) ) return 0;
  zPrompt = mprintf("\n%s authorization required by\n%s\n",
    g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
  fossil_print(zPrompt);
  free(zPrompt);
  if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
    zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
  }else{
    prompt_user("Basic Authorization user: ", &x);
    zUser = mprintf("%b", &x);
    zPrompt = mprintf("HTTP password for %b: ", &x);







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  char *zUser;
  char *zPw;
  char *zPrompt;
  char *zHttpAuth = 0;
  if( !isatty(fileno(stdin)) ) return 0;
  zPrompt = mprintf("\n%s authorization required by\n%s\n",
    g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
  fossil_print("%s", zPrompt);
  free(zPrompt);
  if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
    zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
  }else{
    prompt_user("Basic Authorization user: ", &x);
    zUser = mprintf("%b", &x);
    zPrompt = mprintf("HTTP password for %b: ", &x);
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  int iHttpVersion;     /* Which version of HTTP protocol server uses */
  char *zLine;          /* A single line of the reply header */
  int i;                /* Loop counter */
  int isError = 0;      /* True if the reply is an error message */
  int isCompressed = 1; /* True if the reply is compressed */

  if( transport_open(&g.url) ){
    fossil_warning(transport_errmsg(&g.url));
    return 1;
  }

  /* Construct the login card and prepare the complete payload */
  blob_zero(&login);
  if( useLogin ) http_build_login_card(pSend, &login);
  if( g.fHttpTrace ){







|







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  int iHttpVersion;     /* Which version of HTTP protocol server uses */
  char *zLine;          /* A single line of the reply header */
  int i;                /* Loop counter */
  int isError = 0;      /* True if the reply is an error message */
  int isCompressed = 1; /* True if the reply is compressed */

  if( transport_open(&g.url) ){
    fossil_warning("%s", transport_errmsg(&g.url));
    return 1;
  }

  /* Construct the login card and prepare the complete payload */
  blob_zero(&login);
  if( useLogin ) http_build_login_card(pSend, &login);
  if( g.fHttpTrace ){
Changes to src/info.c.
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
     " WHERE blob.rid=%d"
     "   AND event.objid=%d",
     timeline_utc(), timeline_utc(), rid, rid
  );
  sideBySide = !is_false(PD("sbs","1"));
  if( db_step(&q1)==SQLITE_ROW ){
    const char *zUuid = db_column_text(&q1, 0);
    char *zTitle = mprintf("Check-in [%S]", zUuid);
    char *zEUser, *zEComment;
    const char *zUser;
    const char *zComment;
    const char *zDate;
    const char *zOrigDate;

    style_header(zTitle);
    login_anonymous_available();
    free(zTitle);
    zEUser = db_text(0,
                   "SELECT value FROM tagxref"
                   " WHERE tagid=%d AND rid=%d AND tagtype>0",
                    TAG_USER, rid);
    zEComment = db_text(0,
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_COMMENT, rid);







<






|

<







533
534
535
536
537
538
539

540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
     " WHERE blob.rid=%d"
     "   AND event.objid=%d",
     timeline_utc(), timeline_utc(), rid, rid
  );
  sideBySide = !is_false(PD("sbs","1"));
  if( db_step(&q1)==SQLITE_ROW ){
    const char *zUuid = db_column_text(&q1, 0);

    char *zEUser, *zEComment;
    const char *zUser;
    const char *zComment;
    const char *zDate;
    const char *zOrigDate;

    style_header("Check-in [%S]", zUuid);
    login_anonymous_available();

    zEUser = db_text(0,
                   "SELECT value FROM tagxref"
                   " WHERE tagid=%d AND rid=%d AND tagtype>0",
                    TAG_USER, rid);
    zEComment = db_text(0,
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_COMMENT, rid);
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594

  rid = name_to_rid_www("name");
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }







|







1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592

  rid = name_to_rid_www("name");
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
  }

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
  style_header(descOnly ? "Artifact Description" : "Artifact Content");
  zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( g.perm.Setup ){
    @ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
  }else{
    @ <h2>Artifact %s(zUuid):</h2>
  }
  blob_zero(&downloadName);







|








|







1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
  }

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
  style_header("%s", descOnly ? "Artifact Description" : "Artifact Content");
  zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( g.perm.Setup ){
    @ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
  }else{
    @ <h2>Artifact %s(zUuid):</h2>
  }
  blob_zero(&downloadName);
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
  char *zTktTitle;
  login_check_credentials();
  if( !g.perm.RdTkt ){ login_needed(); return; }
  rid = name_to_rid_www("name");
  if( rid==0 ){ fossil_redirect_home(); }
  zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( g.perm.Admin ){
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }







|







1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
  char *zTktTitle;
  login_check_credentials();
  if( !g.perm.RdTkt ){ login_needed(); return; }
  rid = name_to_rid_www("name");
  if( rid==0 ){ fossil_redirect_home(); }
  zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( g.perm.Admin ){
    if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
    return;
  }else if( rc==2 ){
    cgi_set_parameter("src","info");
    ambiguous_page();
    return;
  }
  zName = blob_str(&uuid);
  rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
  if( rid==0 ){
    style_header("Broken Link");
    @ <p>No such object: %h(zName)</p>
    style_footer();
    return;
  }
  if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){







|







2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
    return;
  }else if( rc==2 ){
    cgi_set_parameter("src","info");
    ambiguous_page();
    return;
  }
  zName = blob_str(&uuid);
  rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
  if( rid==0 ){
    style_header("Broken Link");
    @ <p>No such object: %h(zName)</p>
    style_footer();
    return;
  }
  if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
Changes to src/json.c.
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
** to simplify the trivial use-cases (which don't need a Blob).
*/
cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
                                      char resetBlob){
  Stmt q = empty_Stmt;
  cson_value * pay = NULL;
  assert( blob_size(pSql) > 0 );
  db_prepare(&q, "%s", blob_str(pSql));
  if(resetBlob){
    blob_reset(pSql);
  }
  pay = json_stmt_to_array_of_obj(&q, pTgt);
  db_finalize(&q);
  return pay;








|







1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
** to simplify the trivial use-cases (which don't need a Blob).
*/
cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
                                      char resetBlob){
  Stmt q = empty_Stmt;
  cson_value * pay = NULL;
  assert( blob_size(pSql) > 0 );
  db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
  if(resetBlob){
    blob_reset(pSql);
  }
  pay = json_stmt_to_array_of_obj(&q, pTgt);
  db_finalize(&q);
  return pay;

1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
  jv2 = cson_value_new_object();
  jo2 = cson_value_get_object(jv2);
  cson_object_set(jo, "sqlite", jv2);
  sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
                   sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
  SETBUF(jo2, "version");
  zDb = db_name("repository");
  cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb)));
  cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb)));
  cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.freelist_count", zDb)));
  sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.encoding", zDb));
  SETBUF(jo2, "encoding");
  sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.journal_mode", zDb));
  cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
  return jv;
#undef SETBUF
}










|
|
|
|

|







1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
  jv2 = cson_value_new_object();
  jo2 = cson_value_get_object(jv2);
  cson_object_set(jo, "sqlite", jv2);
  sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
                   sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
  SETBUF(jo2, "version");
  zDb = db_name("repository");
  cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_count", zDb)));
  cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_size", zDb)));
  cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".freelist_count", zDb)));
  sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".encoding", zDb));
  SETBUF(jo2, "encoding");
  sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
  cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
  return jv;
#undef SETBUF
}



2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
                                   Blob * pOut, int filterByMode){
  int i = 0;
  for( ; zPages->name; ++zPages, ++i ){
    if(filterByMode){
      if(g.isHTTP && zPages->runMode < 0) continue;
      else if(zPages->runMode > 0) continue;
    }
    blob_appendf(pOut, zPages->name, -1);
    if((zPages+1)->name){
      blob_append(pOut, ", ",2);
    }
  }
  return i;
}








|







2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
                                   Blob * pOut, int filterByMode){
  int i = 0;
  for( ; zPages->name; ++zPages, ++i ){
    if(filterByMode){
      if(g.isHTTP && zPages->runMode < 0) continue;
      else if(zPages->runMode > 0) continue;
    }
    blob_append(pOut, zPages->name, -1);
    if((zPages+1)->name){
      blob_append(pOut, ", ",2);
    }
  }
  return i;
}

Changes to src/json_config.c.
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    const struct JsonConfigProperty * prop = &JsonConfigProperties[0];
    blob_append(&sql," OR name IN (",-1);
    for( i = 0; prop->name; ++prop ){
      if(prop->groupMask & confMask){
        if( i++ ){
          blob_append(&sql,",",1);
        }
        blob_appendf(&sql, "%Q", prop->name);
      }
    }
    blob_append(&sql,") ", -1);
  }


  if( optSkinBackups ){
    blob_append(&sql, " OR name GLOB 'skin:*'", -1);
  }
  blob_append(&sql," ORDER BY name", -1);
  db_prepare(&q, blob_str(&sql));
  blob_reset(&sql);
  pay = cson_new_object();
  while( (SQLITE_ROW==db_step(&q)) ){
    cson_object_set(pay,
                    db_column_text(&q,0),
                    json_new_string(db_column_text(&q,1)));
  }







|










|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    const struct JsonConfigProperty * prop = &JsonConfigProperties[0];
    blob_append(&sql," OR name IN (",-1);
    for( i = 0; prop->name; ++prop ){
      if(prop->groupMask & confMask){
        if( i++ ){
          blob_append(&sql,",",1);
        }
        blob_append_sql(&sql, "%Q", prop->name);
      }
    }
    blob_append(&sql,") ", -1);
  }


  if( optSkinBackups ){
    blob_append(&sql, " OR name GLOB 'skin:*'", -1);
  }
  blob_append(&sql," ORDER BY name", -1);
  db_prepare(&q, "%s", blob_sql_text(&sql));
  blob_reset(&sql);
  pay = cson_new_object();
  while( (SQLITE_ROW==db_step(&q)) ){
    cson_object_set(pay,
                    db_column_text(&q,0),
                    json_new_string(db_column_text(&q,1)));
  }
Changes to src/json_finfo.c.
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  }
  
  zBefore = json_find_option_cstr("before",NULL,"b");
  zAfter = json_find_option_cstr("after",NULL,"a");
  limit = json_find_option_int("limit",NULL,"n", -1);
  zCheckin = json_find_option_cstr("checkin",NULL,"ci");

  blob_appendf(&sql, 
/*0*/   "SELECT b.uuid,"
/*1*/   "   ci.uuid,"
/*2*/   "   (SELECT uuid FROM blob WHERE rid=mlink.fid),"  /* Current file uuid */
/*3*/   "   cast(strftime('%%s',event.mtime) AS INTEGER),"
/*4*/   "   coalesce(event.euser, event.user),"
/*5*/   "   coalesce(event.ecomment, event.comment),"
/*6*/   " (SELECT uuid FROM blob WHERE rid=mlink.pid),"  /* Parent file uuid */







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  }
  
  zBefore = json_find_option_cstr("before",NULL,"b");
  zAfter = json_find_option_cstr("after",NULL,"a");
  limit = json_find_option_int("limit",NULL,"n", -1);
  zCheckin = json_find_option_cstr("checkin",NULL,"ci");

  blob_append_sql(&sql, 
/*0*/   "SELECT b.uuid,"
/*1*/   "   ci.uuid,"
/*2*/   "   (SELECT uuid FROM blob WHERE rid=mlink.fid),"  /* Current file uuid */
/*3*/   "   cast(strftime('%%s',event.mtime) AS INTEGER),"
/*4*/   "   coalesce(event.euser, event.user),"
/*5*/   "   coalesce(event.ecomment, event.comment),"
/*6*/   " (SELECT uuid FROM blob WHERE rid=mlink.pid),"  /* Parent file uuid */
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    /*printf("zCheckin=[%s], zU=[%s]", zCheckin, zU);*/
    if(rc<=0){
      json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
                   "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
      blob_reset(&sql);
      return NULL;
    }
    blob_appendf(&sql, " AND ci.uuid='%q'", zU);
    free(zU);
  }else{
    if( zAfter && *zAfter ){
      blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter);
      sort = 1;
    }else if( zBefore && *zBefore ){
      blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore);
    }
  }

  blob_appendf(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
  /*printf("SQL=\n%s\n",blob_str(&sql));*/
  db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding
                                       SQL escapes*/);
  blob_reset(&sql);

  pay = cson_new_object();
  cson_object_set(pay, "name", json_new_string(zFilename));
  if( limit > 0 ){
    cson_object_set(pay, "limit", json_new_int(limit));
  }







|



|


|



|

|
<







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
    /*printf("zCheckin=[%s], zU=[%s]", zCheckin, zU);*/
    if(rc<=0){
      json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
                   "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
      blob_reset(&sql);
      return NULL;
    }
    blob_append_sql(&sql, " AND ci.uuid='%q'", zU);
    free(zU);
  }else{
    if( zAfter && *zAfter ){
      blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zAfter);
      sort = 1;
    }else if( zBefore && *zBefore ){
      blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zBefore);
    }
  }

  blob_append_sql(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
  /*printf("SQL=\n%s\n",blob_str(&sql));*/
  db_prepare(&q, "%s", blob_sql_text(&sql));

  blob_reset(&sql);

  pay = cson_new_object();
  cson_object_set(pay, "name", json_new_string(zFilename));
  if( limit > 0 ){
    cson_object_set(pay, "limit", json_new_int(limit));
  }
Changes to src/json_query.c.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    json_set_err(FSL_JSON_E_MISSING_ARGS,
                 "'sql' (-s) argument is missing.");
    return NULL;
  }

  zFmt = json_find_option_cstr2("format",NULL,"f",3);
  if(!zFmt) zFmt = "o";
  db_prepare(&q,"%s", zSql);
  if( 0 == sqlite3_column_count( q.pStmt ) ){
      json_set_err(FSL_JSON_E_USAGE,
                   "Input query has no result columns. "
                   "Only SELECT-like queries are supported.");
      db_finalize(&q);
      return NULL;
  }







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    json_set_err(FSL_JSON_E_MISSING_ARGS,
                 "'sql' (-s) argument is missing.");
    return NULL;
  }

  zFmt = json_find_option_cstr2("format",NULL,"f",3);
  if(!zFmt) zFmt = "o";
  db_prepare(&q,"%s", zSql/*safe-for-%s*/);
  if( 0 == sqlite3_column_count( q.pStmt ) ){
      json_set_err(FSL_JSON_E_USAGE,
                   "Input query has no result columns. "
                   "Only SELECT-like queries are supported.");
      db_finalize(&q);
      return NULL;
  }
Changes to src/json_report.c.
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  limit = json_find_option_int("limit",NULL,"n",-1);

  
  /* Copy over report's SQL...*/
  blob_append(&sql, db_column_text(&q,0), -1);
  zTitle = mprintf("%s", db_column_text(&q,1));
  db_finalize(&q);
  db_prepare(&q, "%s", blob_str(&sql));

  /** Build the response... */
  pay = cson_new_object();

  cson_object_set(pay, "report", json_new_int(nReport));
  cson_object_set(pay, "title", json_new_string(zTitle));
  if(limit>0){







|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  limit = json_find_option_int("limit",NULL,"n",-1);

  
  /* Copy over report's SQL...*/
  blob_append(&sql, db_column_text(&q,0), -1);
  zTitle = mprintf("%s", db_column_text(&q,1));
  db_finalize(&q);
  db_prepare(&q, "%s", blob_sql_text(&sql));

  /** Build the response... */
  pay = cson_new_object();

  cson_object_set(pay, "report", json_new_int(nReport));
  cson_object_set(pay, "title", json_new_string(zTitle));
  if(limit>0){
Changes to src/json_tag.c.
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
               "  AND event.type GLOB '%q'"
               "  AND blob.rid IN ("
               "    SELECT rid FROM tagxref"
               "      WHERE tagtype>0 AND tagid=%d"
               "  )"
               " ORDER BY event.mtime DESC"
               "%s LIMIT %d",
               zSqlBase, zType, tagid,
               (limit>0)?"":"--", limit
               );
    listV = json_stmt_to_array_of_obj(&q, NULL);
    db_finalize(&q);
  }

  if(!listV) {







|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
               "  AND event.type GLOB '%q'"
               "  AND blob.rid IN ("
               "    SELECT rid FROM tagxref"
               "      WHERE tagtype>0 AND tagid=%d"
               "  )"
               " ORDER BY event.mtime DESC"
               "%s LIMIT %d",
               zSqlBase /*safe-for-%s*/, zType, tagid,
               (limit>0)?"":"--", limit
               );
    listV = json_stmt_to_array_of_obj(&q, NULL);
    db_finalize(&q);
  }

  if(!listV) {
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
                -1
                );
    if(!fTicket){
      blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
    }
    blob_append(&sql,
                " ORDER BY tagname", -1);
    db_prepare(&q, blob_buffer(&sql));
    blob_reset(&sql);
    cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
    while( SQLITE_ROW == db_step(&q) ){
      const char *zName = db_column_text(&q, 0);
      if(NULL==arV){
        arV = cson_value_new_array();
        ar = cson_value_get_array(arV);







|







440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
                -1
                );
    if(!fTicket){
      blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
    }
    blob_append(&sql,
                " ORDER BY tagname", -1);
    db_prepare(&q, "%s", blob_sql_text(&sql));
    blob_reset(&sql);
    cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
    while( SQLITE_ROW == db_step(&q) ){
      const char *zName = db_column_text(&q, 0);
      if(NULL==arV){
        arV = cson_value_new_array();
        ar = cson_value_get_array(arV);
Changes to src/json_timeline.c.
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    @   bgColor TEXT,
    @   eventType TEXT,
    @   tags TEXT,
    @   tagId INTEGER,
    @   brief TEXT
    @ )
  ;
  db_multi_exec(zSql);
}

/*
** Return a pointer to a constant string that forms the basis
** for a timeline query for the JSON interface.
*/
char const * json_timeline_query(void){







|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    @   bgColor TEXT,
    @   eventType TEXT,
    @   tags TEXT,
    @   tagId INTEGER,
    @   brief TEXT
    @ )
  ;
  db_multi_exec("%s", zSql /*safe-for-%s*/);
}

/*
** Return a pointer to a constant string that forms the basis
** for a timeline query for the JSON interface.
*/
char const * json_timeline_query(void){
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
              "  coalesce(euser, user) as user,"
              "  blob.rid IN leaf as isLeaf,"
              "  bgcolor as bgColor"
              " FROM event JOIN blob"
              " WHERE blob.rid=event.objid",
              -1);

  blob_appendf(&sql,
               " AND event.type='ci'"
               " AND blob.rid IN (SELECT rid FROM tagxref"
               "  WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
               " ORDER BY event.mtime DESC",
               TAG_BRANCH);
  limit = json_timeline_limit(20);
  if(limit>0){
    blob_appendf(&sql," LIMIT %d ",limit);
  }
  db_prepare(&q,"%s", blob_str(&sql));
  blob_reset(&sql);
  pay = json_stmt_to_array_of_obj(&q, NULL);
  db_finalize(&q);
  assert(NULL != pay);
  if(pay){
    /* get the array-form tags of each record. */
    cson_string * tags = cson_new_string("tags",4);







|







|

|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
              "  coalesce(euser, user) as user,"
              "  blob.rid IN leaf as isLeaf,"
              "  bgcolor as bgColor"
              " FROM event JOIN blob"
              " WHERE blob.rid=event.objid",
              -1);

  blob_append_sql(&sql,
               " AND event.type='ci'"
               " AND blob.rid IN (SELECT rid FROM tagxref"
               "  WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
               " ORDER BY event.mtime DESC",
               TAG_BRANCH);
  limit = json_timeline_limit(20);
  if(limit>0){
    blob_append_sql(&sql," LIMIT %d ",limit);
  }
  db_prepare(&q,"%s", blob_sql_text(&sql));
  blob_reset(&sql);
  pay = json_stmt_to_array_of_obj(&q, NULL);
  db_finalize(&q);
  assert(NULL != pay);
  if(pay){
    /* get the array-form tags of each record. */
    cson_string * tags = cson_new_string("tags",4);
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  } (void)0

#if 0
  /* only for testing! */
  tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
  SET("timelineSql");
#endif
  db_multi_exec(blob_buffer(&sql));
  blob_reset(&sql);
  db_prepare(&q, "SELECT "
             " rid AS rid"
             " FROM json_timeline"
             " ORDER BY rowid");
  listV = cson_value_new_array();
  list = cson_value_get_array(listV);







|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  } (void)0

#if 0
  /* only for testing! */
  tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
  SET("timelineSql");
#endif
  db_multi_exec("%s", blob_buffer(&sql)/*safe-for-%s*/);
  blob_reset(&sql);
  db_prepare(&q, "SELECT "
             " rid AS rid"
             " FROM json_timeline"
             " ORDER BY rowid");
  listV = cson_value_new_array();
  list = cson_value_get_array(listV);
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
  }

#if 0
  /* only for testing! */
  tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
  SET("timelineSql");
#endif
  db_multi_exec(blob_buffer(&sql));
  blob_reset(&sql);
  db_prepare(&q, "SELECT"
             " uuid AS uuid,"
             " mtime AS timestamp,"
#if 0
             " timestampString AS timestampString,"
#endif
             " comment AS comment, "
             " user AS user,"
             " eventType AS eventType"
#if 0
             /* can wiki pages have tags? */
             " tags AS tags," /*FIXME: split this into
                                a JSON array*/
             " tagId AS tagId,"
#endif
             " FROM json_timeline"
             " ORDER BY rowid",
             -1);
  list = cson_new_array();
  json_stmt_to_array_of_obj(&q, list);
  cson_object_set(pay, "timeline", cson_array_value(list));
  goto ok;
  error:
  assert( 0 != g.json.resultCode );
  cson_value_free(payV);







|

















|
<







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
  }

#if 0
  /* only for testing! */
  tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
  SET("timelineSql");
#endif
  db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
  blob_reset(&sql);
  db_prepare(&q, "SELECT"
             " uuid AS uuid,"
             " mtime AS timestamp,"
#if 0
             " timestampString AS timestampString,"
#endif
             " comment AS comment, "
             " user AS user,"
             " eventType AS eventType"
#if 0
             /* can wiki pages have tags? */
             " tags AS tags," /*FIXME: split this into
                                a JSON array*/
             " tagId AS tagId,"
#endif
             " FROM json_timeline"
             " ORDER BY rowid");

  list = cson_new_array();
  json_stmt_to_array_of_obj(&q, list);
  cson_object_set(pay, "timeline", cson_array_value(list));
  goto ok;
  error:
  assert( 0 != g.json.resultCode );
  cson_value_free(payV);
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
  pay = cson_value_get_object(payV);
  check = json_timeline_setup_sql( "t", &sql, pay );
  if(check){
    json_set_err(check, "Query initialization failed.");
    goto error;
  }

  db_multi_exec(blob_buffer(&sql));
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
    json_set_err((cson_rc.AllocError==check)        \
                 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN,      \
                 "Object property insertion failed."); \
    goto error;\
  } (void)0








|







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
  pay = cson_value_get_object(payV);
  check = json_timeline_setup_sql( "t", &sql, pay );
  if(check){
    json_set_err(check, "Query initialization failed.");
    goto error;
  }

  db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
    json_set_err((cson_rc.AllocError==check)        \
                 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN,      \
                 "Object property insertion failed."); \
    goto error;\
  } (void)0

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
             " timestampString AS timestampString,"
#endif
             " user AS user,"
             " eventType AS eventType,"
             " comment AS comment,"
             " brief AS briefComment"
             " FROM json_timeline"
             " ORDER BY rowid",
             -1);
  listV = cson_value_new_array();
  list = cson_value_get_array(listV);
  tmp = listV;
  SET("timeline");
  while( (SQLITE_ROW == db_step(&q) )){
    /* convert each row into a JSON object...*/
    int rc;







|
<







635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
             " timestampString AS timestampString,"
#endif
             " user AS user,"
             " eventType AS eventType,"
             " comment AS comment,"
             " brief AS briefComment"
             " FROM json_timeline"
             " ORDER BY rowid");

  listV = cson_value_new_array();
  list = cson_value_get_array(listV);
  tmp = listV;
  SET("timeline");
  while( (SQLITE_ROW == db_step(&q) )){
    /* convert each row into a JSON object...*/
    int rc;
Changes to src/json_user.c.
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
      }
      forceLogout = cson_value_true()
        /* reminders: 1) does not allocate.
           2) we do this because changing a name
           invalidates any login token because the old name
           is part of the token hash.
        */;
      blob_appendf(&sql, ", login=%Q", zNameNew);
      ++gotFields;
    }
  }

  if( zCap && *zCap ){
    if(!g.perm.Admin || !g.perm.Setup){
      /* we "could" arguably silently ignore cap in this case. */
      json_set_err(FSL_JSON_E_DENIED,
                   "Changing capabilities requires 'a' or 's' privileges.");
      goto error;
    }
    blob_appendf(&sql, ", cap=%Q", zCap);
    ++gotFields;
  }

  if( zPW && *zPW ){
    if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
      json_set_err( FSL_JSON_E_DENIED,
                    "Password change requires 'a', 's', "
                    "or 'p' permissions.");
      goto error;
    }else{
#define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
#if !TRY_LOGIN_GROUP
      char * zPWHash = NULL;
      ++gotFields;
      zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
      blob_appendf(&sql, ", pw=%Q", zPWHash);
      free(zPWHash);
#else
      ++gotFields;
      blob_appendf(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
                   "(SELECT value FROM config WHERE name='project-code')))",
                   zPW, zNameNew ? zNameNew : zName);
      /* shared_secret() func is undefined? */
#endif
    }
  }

  if( zInfo ){
    blob_appendf(&sql, ", info=%Q", zInfo);
    ++gotFields;
  }

  if((g.perm.Admin || g.perm.Setup)
     && forceLogout && cson_value_get_bool(forceLogout)){
    blob_append(&sql, ", cookie=NULL, cexpire=NULL", -1);
    ++gotFields;
  }
  
  if(!gotFields){
    json_set_err( FSL_JSON_E_MISSING_ARGS,
                  "Required user data are missing.");
    goto error;
  }
  assert(uid>0);
#if !TRY_LOGIN_GROUP
  blob_appendf(&sql, " WHERE uid=%d", uid);
#else /* need name for login group support :/ */
  blob_appendf(&sql, " WHERE login=%Q", zName);
#endif
#if 0
  puts(blob_str(&sql));
  cson_output_FILE( cson_object_value(pUser), stdout, NULL );
#endif
  db_prepare(&q, "%s", blob_str(&sql));
  db_exec(&q);
  db_finalize(&q);
#if TRY_LOGIN_GROUP
  if( zPW || cson_value_get_bool(forceLogout) ){
    Blob groupSql = empty_blob;
    char * zErr = NULL;
    blob_appendf(&groupSql,
      "INSERT INTO user(login)"
      "  SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
      zName, zName
    );
    blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
    login_group_sql(blob_str(&groupSql), NULL, NULL, &zErr);
    blob_reset(&groupSql);







|











|















|



|








|
















|

|





|






|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
      }
      forceLogout = cson_value_true()
        /* reminders: 1) does not allocate.
           2) we do this because changing a name
           invalidates any login token because the old name
           is part of the token hash.
        */;
      blob_append_sql(&sql, ", login=%Q", zNameNew);
      ++gotFields;
    }
  }

  if( zCap && *zCap ){
    if(!g.perm.Admin || !g.perm.Setup){
      /* we "could" arguably silently ignore cap in this case. */
      json_set_err(FSL_JSON_E_DENIED,
                   "Changing capabilities requires 'a' or 's' privileges.");
      goto error;
    }
    blob_append_sql(&sql, ", cap=%Q", zCap);
    ++gotFields;
  }

  if( zPW && *zPW ){
    if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
      json_set_err( FSL_JSON_E_DENIED,
                    "Password change requires 'a', 's', "
                    "or 'p' permissions.");
      goto error;
    }else{
#define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
#if !TRY_LOGIN_GROUP
      char * zPWHash = NULL;
      ++gotFields;
      zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
      blob_append_sql(&sql, ", pw=%Q", zPWHash);
      free(zPWHash);
#else
      ++gotFields;
      blob_append_sql(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
                   "(SELECT value FROM config WHERE name='project-code')))",
                   zPW, zNameNew ? zNameNew : zName);
      /* shared_secret() func is undefined? */
#endif
    }
  }

  if( zInfo ){
    blob_append_sql(&sql, ", info=%Q", zInfo);
    ++gotFields;
  }

  if((g.perm.Admin || g.perm.Setup)
     && forceLogout && cson_value_get_bool(forceLogout)){
    blob_append(&sql, ", cookie=NULL, cexpire=NULL", -1);
    ++gotFields;
  }
  
  if(!gotFields){
    json_set_err( FSL_JSON_E_MISSING_ARGS,
                  "Required user data are missing.");
    goto error;
  }
  assert(uid>0);
#if !TRY_LOGIN_GROUP
  blob_append_sql(&sql, " WHERE uid=%d", uid);
#else /* need name for login group support :/ */
  blob_append_sql(&sql, " WHERE login=%Q", zName);
#endif
#if 0
  puts(blob_str(&sql));
  cson_output_FILE( cson_object_value(pUser), stdout, NULL );
#endif
  db_prepare(&q, "%s", blob_sql_text(&sql));
  db_exec(&q);
  db_finalize(&q);
#if TRY_LOGIN_GROUP
  if( zPW || cson_value_get_bool(forceLogout) ){
    Blob groupSql = empty_blob;
    char * zErr = NULL;
    blob_append_sql(&groupSql,
      "INSERT INTO user(login)"
      "  SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
      zName, zName
    );
    blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
    login_group_sql(blob_str(&groupSql), NULL, NULL, &zErr);
    blob_reset(&groupSql);
Changes to src/json_wiki.c.
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
  }
  blob_append(&sql,"SELECT"
              " substr(tagname,6) as name"
              " FROM tag WHERE tagname GLOB 'wiki-*'",
              -1);
  zGlob = json_find_option_cstr("glob",NULL,"g");
  if(zGlob && *zGlob){
    blob_appendf(&sql," AND name %s GLOB %Q",
                 fInvert ? "NOT" : "", zGlob);
  }else{
    zGlob = json_find_option_cstr("like",NULL,"l");
    if(zGlob && *zGlob){
      blob_appendf(&sql," AND name %s LIKE %Q",
                   fInvert ? "NOT" : "",
                   zGlob);
    }
  }
  blob_append(&sql," ORDER BY lower(name)", -1);
  db_prepare(&q,"%s", blob_str(&sql));
  blob_reset(&sql);
  listV = cson_value_new_array();
  list = cson_value_get_array(listV);
  while( SQLITE_ROW == db_step(&q) ){
    cson_value * v;
    if( verbose ){
      char const * name = db_column_text(&q,0);







|
|



|
|
<



|







442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463
464
465
466
  }
  blob_append(&sql,"SELECT"
              " substr(tagname,6) as name"
              " FROM tag WHERE tagname GLOB 'wiki-*'",
              -1);
  zGlob = json_find_option_cstr("glob",NULL,"g");
  if(zGlob && *zGlob){
    blob_append_sql(&sql," AND name %s GLOB %Q",
                    fInvert ? "NOT" : "", zGlob);
  }else{
    zGlob = json_find_option_cstr("like",NULL,"l");
    if(zGlob && *zGlob){
      blob_append_sql(&sql," AND name %s LIKE %Q",
                      fInvert ? "NOT" : "", zGlob);

    }
  }
  blob_append(&sql," ORDER BY lower(name)", -1);
  db_prepare(&q,"%s", blob_sql_text(&sql));
  blob_reset(&sql);
  listV = cson_value_new_array();
  list = cson_value_get_array(listV);
  while( SQLITE_ROW == db_step(&q) ){
    cson_value * v;
    if( verbose ){
      char const * name = db_column_text(&q,0);
Changes to src/leaf.c.
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
    @ SELECT 1 FROM plink
    @  WHERE pid=%d
    @    AND coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.pid), 'trunk')
    @       =coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.cid), 'trunk')
  ;

  rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
  return rc==0;
}

/*
** Count the number of primary non-branch children for the given check-in.
**
** A primary child is one where the parent is the primary parent, not







>
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    @ SELECT 1 FROM plink
    @  WHERE pid=%d
    @    AND coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.pid), 'trunk')
    @       =coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.cid), 'trunk')
  ;
  rc = db_int(0, zSql /*works-like:"%d,%d,%d"*/,
              rid, TAG_BRANCH, TAG_BRANCH);
  return rc==0;
}

/*
** Count the number of primary non-branch children for the given check-in.
**
** A primary child is one where the parent is the primary parent, not
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
    @ SELECT count(*) FROM plink
    @  WHERE pid=:pid AND isprim
    @    AND coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.pid), 'trunk')
    @       =coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.cid), 'trunk')
  ;
  db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH);
  db_bind_int(&q, ":pid", pid);
  if( db_step(&q)==SQLITE_ROW ){
    nNonBranch = db_column_int(&q, 0);
  }
  db_reset(&q);
  return nNonBranch;
}







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    @ SELECT count(*) FROM plink
    @  WHERE pid=:pid AND isprim
    @    AND coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.pid), 'trunk')
    @       =coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.cid), 'trunk')
  ;
  db_static_prepare(&q, zSql /*works-like: "%d,%d"*/, TAG_BRANCH, TAG_BRANCH);
  db_bind_int(&q, ":pid", pid);
  if( db_step(&q)==SQLITE_ROW ){
    nNonBranch = db_column_int(&q, 0);
  }
  db_reset(&q);
  return nNonBranch;
}
Changes to src/loadctrl.c.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
** Return the load average for the host processor
*/
double load_average(void){
#if !defined(_WIN32) && !defined(FOSSIL_OMIT_LOAD_AVERAGE)
  double a[3];
  if( getloadavg(a, 3)>0 ){
    return a[0];
  }
#endif
  return 0.0;
}

/*
** COMMAND: test-loadavg







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
** Return the load average for the host processor
*/
double load_average(void){
#if !defined(_WIN32) && !defined(FOSSIL_OMIT_LOAD_AVERAGE)
  double a[3];
  if( getloadavg(a, 3)>0 ){
    return a[0]>=0.000001 ? a[0] : 0.000001;
  }
#endif
  return 0.0;
}

/*
** COMMAND: test-loadavg
Changes to src/login.c.
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    if( prefix_match("spider", zAgent+i) ) return 0;
    if( prefix_match("crawl", zAgent+i) ) return 0;
    /* If a URI appears in the User-Agent, it is probably a bot */
    if( strncmp("http", zAgent+i,4)==0 ) return 0;
  }
  if( strncmp(zAgent, "Mozilla/", 8)==0 ){
    if( atoi(&zAgent[8])<4 ) return 0;  /* Many bots advertise as Mozilla/3 */
    if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
    if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
    if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
    if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */
    if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
    return 0;
  }
  if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
  if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
  if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
  if( strncmp(zAgent, "NetSurf/", 8)==0 ) return 1;
  return 0;







|
|
|
|
|







393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    if( prefix_match("spider", zAgent+i) ) return 0;
    if( prefix_match("crawl", zAgent+i) ) return 0;
    /* If a URI appears in the User-Agent, it is probably a bot */
    if( strncmp("http", zAgent+i,4)==0 ) return 0;
  }
  if( strncmp(zAgent, "Mozilla/", 8)==0 ){
    if( atoi(&zAgent[8])<4 ) return 0;  /* Many bots advertise as Mozilla/3 */
    if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1;
    if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1;
    if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1;
    if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */
    if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1;
    return 0;
  }
  if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
  if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
  if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
  if( strncmp(zAgent, "NetSurf/", 8)==0 ) return 1;
  return 0;
473
474
475
476
477
478
479










480
481
482
483
484
485
486
  char *zErrMsg = "";
  int uid;                     /* User id logged in user */
  char *zSha1Pw;
  const char *zIpAddr;         /* IP address of requestor */
  const char *zReferer;

  login_check_credentials();










  sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
                  constant_time_cmp_function, 0, 0);
  zUsername = P("u");
  zPasswd = P("p");
  anonFlag = P("anon")!=0;
  if( P("out")!=0 ){
    login_clear_login_data();







>
>
>
>
>
>
>
>
>
>







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
  char *zErrMsg = "";
  int uid;                     /* User id logged in user */
  char *zSha1Pw;
  const char *zIpAddr;         /* IP address of requestor */
  const char *zReferer;

  login_check_credentials();
  if( login_wants_https_redirect() ){
    const char *zQS = P("QUERY_STRING");
    if( zQS==0 ){
      zQS = "";
    }else if( zQS[0]!=0 ){
      zQS = mprintf("?%s", zQS);
    }
    cgi_redirectf("%s%s%s", g.zHttpsURL, P("PATH_INFO"), zQS);
    return;    
  }
  sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
                  constant_time_cmp_function, 0, 0);
  zUsername = P("u");
  zPasswd = P("p");
  anonFlag = P("anon")!=0;
  if( P("out")!=0 ){
    login_clear_login_data();
774
775
776
777
778
779
780















781
782
783
784
785
786
787
    "   AND length(cap)>0"
    "   AND length(pw)>0"
    "   AND constant_time_cmp(cookie,%Q)=0",
    zLogin, zRemoteAddr, zCookie
  );
  return uid;
}
















/*
** This routine examines the login cookie to see if it exists and
** is valid.  If the login cookie checks out, it then sets global
** variables appropriately.
**
**    g.userUid      Database USER.UID value.  Might be -1 for "nobody"







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
    "   AND length(cap)>0"
    "   AND length(pw)>0"
    "   AND constant_time_cmp(cookie,%Q)=0",
    zLogin, zRemoteAddr, zCookie
  );
  return uid;
}

/*
** Return true if it is appropriate to redirect login requests to HTTPS.
**
** Redirect to https is appropriate if all of the above are true:
**    (1) The redirect-to-https flag is set
**    (2) The current connection is http, not https or ssh
**    (3) The sslNotAvailable flag is clear
*/
int login_wants_https_redirect(void){
  if( g.sslNotAvailable ) return 0;
  if( db_get_boolean("redirect-to-https",0)==0 ) return 0;
  if( P("HTTPS")!=0 ) return 0;
  return 1;
}

/*
** This routine examines the login cookie to see if it exists and
** is valid.  If the login cookie checks out, it then sets global
** variables appropriately.
**
**    g.userUid      Database USER.UID value.  Might be -1 for "nobody"
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
  ** then there is no need to check user credentials.
  **
  ** This feature allows the "fossil ui" command to give the user
  ** full access rights without having to log in.
  */
  zRemoteAddr = ipPrefix(zIpAddr = PD("REMOTE_ADDR","nil"));
  if( ( fossil_strcmp(zIpAddr, "127.0.0.1")==0 ||
        g.fSshClient & CGI_SSH_CLIENT )
   && g.useLocalauth
   && db_get_int("localauth",0)==0
   && P("HTTPS")==0
  ){
    if( g.localOpen ) zLogin = db_lget("default-user",0);
    if( zLogin!=0 ){
      uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zLogin);







|







835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
  ** then there is no need to check user credentials.
  **
  ** This feature allows the "fossil ui" command to give the user
  ** full access rights without having to log in.
  */
  zRemoteAddr = ipPrefix(zIpAddr = PD("REMOTE_ADDR","nil"));
  if( ( fossil_strcmp(zIpAddr, "127.0.0.1")==0 ||
        (g.fSshClient & CGI_SSH_CLIENT)!=0 )
   && g.useLocalauth
   && db_get_int("localauth",0)==0
   && P("HTTPS")==0
  ){
    if( g.localOpen ) zLogin = db_lget("default-user",0);
    if( zLogin!=0 ){
      uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zLogin);
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
        @ %s(zUsername) already exists.
        @ </span></p>
      }else{
        char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
        int uid;
        db_multi_exec(
            "INSERT INTO user(login,pw,cap,info,mtime)"
            "VALUES(%B,%Q,%B,%B,strftime('%s','now'))",
            &login, zPw, &caps, &contact
            );
        free(zPw);

        /* The user is registered, now just log him in. */
        uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername);
        login_set_user_cookie( zUsername, uid, NULL );







|







1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
        @ %s(zUsername) already exists.
        @ </span></p>
      }else{
        char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
        int uid;
        db_multi_exec(
            "INSERT INTO user(login,pw,cap,info,mtime)"
            "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
            &login, zPw, &caps, &contact
            );
        free(zPw);

        /* The user is registered, now just log him in. */
        uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername);
        login_set_user_cookie( zUsername, uid, NULL );
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
  const char *zSelf;         /* The ATTACH name of our repository */

  *pzErrMsg = 0;   /* Default to no errors */
  zSelf = db_name("repository");

  /* Get the full pathname of the other repository */
  file_canonical_name(zRepo, &fullName, 0);
  zRepo = mprintf(blob_str(&fullName));
  blob_reset(&fullName);

  /* Get the full pathname for our repository.  Also the project code
  ** and project name for ourself. */
  file_canonical_name(g.zRepositoryName, &fullName, 0);
  zSelfRepo = mprintf(blob_str(&fullName));
  blob_reset(&fullName);
  zSelfProjCode = db_get("project-code", "unknown");
  zSelfLabel = db_get("project-name", 0);
  if( zSelfLabel==0 ){
    zSelfLabel = zSelfProjCode;
  }








|





|







1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
  const char *zSelf;         /* The ATTACH name of our repository */

  *pzErrMsg = 0;   /* Default to no errors */
  zSelf = db_name("repository");

  /* Get the full pathname of the other repository */
  file_canonical_name(zRepo, &fullName, 0);
  zRepo = fossil_strdup(blob_str(&fullName));
  blob_reset(&fullName);

  /* Get the full pathname for our repository.  Also the project code
  ** and project name for ourself. */
  file_canonical_name(g.zRepositoryName, &fullName, 0);
  zSelfRepo = fossil_strdup(blob_str(&fullName));
  blob_reset(&fullName);
  zSelfProjCode = db_get("project-code", "unknown");
  zSelfLabel = db_get("project-name", 0);
  if( zSelfLabel==0 ){
    zSelfLabel = zSelfProjCode;
  }

1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
  }
  rc = sqlite3_open_v2(
       zRepo, &pOther,
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       g.zVfsName
  );
  if( rc!=SQLITE_OK ){
    *pzErrMsg = mprintf(sqlite3_errmsg(pOther));
  }else{
    rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
  }
  sqlite3_close(pOther);
  if( rc ) return;

  /* Attach the other repository.  Make sure the username/password is







|







1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
  }
  rc = sqlite3_open_v2(
       zRepo, &pOther,
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       g.zVfsName
  );
  if( rc!=SQLITE_OK ){
    *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther));
  }else{
    rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
  }
  sqlite3_close(pOther);
  if( rc ) return;

  /* Attach the other repository.  Make sure the username/password is
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
  /* Create all the necessary CONFIG table entries on both the
  ** other repository and on our own repository.
  */
  zSelfProjCode = abbreviated_project_code(zSelfProjCode);
  zOtherProjCode = abbreviated_project_code(zOtherProjCode);
  db_begin_transaction();
  db_multi_exec(
    "DELETE FROM %s.config WHERE name GLOB 'peer-*';"
    "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);"
    "INSERT INTO %s.config(name,value) "
    "  SELECT 'peer-name-%q', value FROM other.config"
    "   WHERE name='project-name';",
    zSelf,
    zSelf, zOtherProjCode, zRepo,
    zSelf, zOtherProjCode
  );
  db_multi_exec(
    "INSERT OR IGNORE INTO other.config(name,value)"
    " VALUES('login-group-name',%Q);"
    "INSERT OR IGNORE INTO other.config(name,value)"
    " VALUES('login-group-code',lower(hex(randomblob(8))));",
    zNewName
  );
  db_multi_exec(
    "REPLACE INTO %s.config(name,value)"
    "  SELECT name, value FROM other.config"
    "   WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
    zSelf
  );
  db_end_transaction(0);
  db_multi_exec("DETACH other");








|
|
|














|







1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
  /* Create all the necessary CONFIG table entries on both the
  ** other repository and on our own repository.
  */
  zSelfProjCode = abbreviated_project_code(zSelfProjCode);
  zOtherProjCode = abbreviated_project_code(zOtherProjCode);
  db_begin_transaction();
  db_multi_exec(
    "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';"
    "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);"
    "INSERT INTO \"%w\".config(name,value) "
    "  SELECT 'peer-name-%q', value FROM other.config"
    "   WHERE name='project-name';",
    zSelf,
    zSelf, zOtherProjCode, zRepo,
    zSelf, zOtherProjCode
  );
  db_multi_exec(
    "INSERT OR IGNORE INTO other.config(name,value)"
    " VALUES('login-group-name',%Q);"
    "INSERT OR IGNORE INTO other.config(name,value)"
    " VALUES('login-group-code',lower(hex(randomblob(8))));",
    zNewName
  );
  db_multi_exec(
    "REPLACE INTO \"%w\".config(name,value)"
    "  SELECT name, value FROM other.config"
    "   WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
    zSelf
  );
  db_end_transaction(0);
  db_multi_exec("DETACH other");

Changes to src/main.c.
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  sqlite3 *dbConfig;      /* Separate connection for global_config table */
  int useAttach;          /* True if global_config is attached to repository */
  const char *zConfigDbName;/* Path of the config database. NULL if not open */
  sqlite3_int64 now;      /* Seconds since 1970 */
  int repositoryOpen;     /* True if the main repository database is open */
  char *zRepositoryOption; /* Most recent cached repository option value */
  char *zRepositoryName;  /* Name of the repository database */

  const char *zMainDbType;/* "configdb", "localdb", or "repository" */
  const char *zConfigDbType;  /* "configdb", "localdb", or "repository" */
  int localOpen;          /* True if the local database is open */
  char *zLocalRoot;       /* The directory holding the  local database */
  int minPrefix;          /* Number of digits needed for a distinct UUID */
  int fSqlTrace;          /* True if --sqltrace flag is present */
  int fSqlStats;          /* True if --sqltrace or --sqlstats are present */
  int fSqlPrint;          /* True if -sqlprint flag is present */
  int fQuiet;             /* True if -quiet flag is present */
  int fHttpTrace;         /* Trace outbound HTTP requests */
  char *zHttpAuth;        /* HTTP Authorization user:pass information */
  int fSystemTrace;       /* Trace calls to fossil_system(), --systemtrace */
  int fSshTrace;          /* Trace the SSH setup traffic */
  int fSshClient;         /* HTTP client flags for SSH client */
  char *zSshCmd;          /* SSH command string */
  int fNoSync;            /* Do not do an autosync ever.  --nosync */
  char *zPath;            /* Name of webpage being served */
  char *zExtra;           /* Extra path information past the webpage name */
  char *zBaseURL;         /* Full text of the URL being served */

  char *zTop;             /* Parent directory of zPath */
  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 */
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* Write error and status messages to CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
  int fullHttpReply;      /* True for full HTTP reply.  False for CGI reply */
  Th_Interp *interp;      /* The TH1 interpreter */
  char *th1Setup;         /* The TH1 post-creation setup script, if any */
  int th1Flags;           /* The TH1 integration state flags */
  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */
  int wikiFlags;          /* Wiki conversion flags applied to %w and %W */
  char isHTTP;            /* True if server/CGI modes, else assume CLI. */
  char javascriptHyperlink; /* If true, set href= using script, not HTML */
  Blob httpHeader;        /* Complete text of the HTTP request header */
  UrlData url;            /* Information about current URL */
  const char *zLogin;     /* Login name.  NULL or "" if not logged in. */
  const char *zSSLIdentity;  /* Value of --ssl-identity option, filename of
                             ** SSL client identity */







>



















>



















|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
  sqlite3 *dbConfig;      /* Separate connection for global_config table */
  int useAttach;          /* True if global_config is attached to repository */
  const char *zConfigDbName;/* Path of the config database. NULL if not open */
  sqlite3_int64 now;      /* Seconds since 1970 */
  int repositoryOpen;     /* True if the main repository database is open */
  char *zRepositoryOption; /* Most recent cached repository option value */
  char *zRepositoryName;  /* Name of the repository database */
  char *zLocalDbName;     /* Name of the local database */
  const char *zMainDbType;/* "configdb", "localdb", or "repository" */
  const char *zConfigDbType;  /* "configdb", "localdb", or "repository" */
  int localOpen;          /* True if the local database is open */
  char *zLocalRoot;       /* The directory holding the  local database */
  int minPrefix;          /* Number of digits needed for a distinct UUID */
  int fSqlTrace;          /* True if --sqltrace flag is present */
  int fSqlStats;          /* True if --sqltrace or --sqlstats are present */
  int fSqlPrint;          /* True if -sqlprint flag is present */
  int fQuiet;             /* True if -quiet flag is present */
  int fHttpTrace;         /* Trace outbound HTTP requests */
  char *zHttpAuth;        /* HTTP Authorization user:pass information */
  int fSystemTrace;       /* Trace calls to fossil_system(), --systemtrace */
  int fSshTrace;          /* Trace the SSH setup traffic */
  int fSshClient;         /* HTTP client flags for SSH client */
  char *zSshCmd;          /* SSH command string */
  int fNoSync;            /* Do not do an autosync ever.  --nosync */
  char *zPath;            /* Name of webpage being served */
  char *zExtra;           /* Extra path information past the webpage name */
  char *zBaseURL;         /* Full text of the URL being served */
  char *zHttpsURL;        /* zBaseURL translated to https: */
  char *zTop;             /* Parent directory of zPath */
  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 */
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* Write error and status messages to CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
  int fullHttpReply;      /* True for full HTTP reply.  False for CGI reply */
  Th_Interp *interp;      /* The TH1 interpreter */
  char *th1Setup;         /* The TH1 post-creation setup script, if any */
  int th1Flags;           /* The TH1 integration state flags */
  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */
  int wikiFlags;          /* Wiki conversion flags applied to %W */
  char isHTTP;            /* True if server/CGI modes, else assume CLI. */
  char javascriptHyperlink; /* If true, set href= using script, not HTML */
  Blob httpHeader;        /* Complete text of the HTTP request header */
  UrlData url;            /* Information about current URL */
  const char *zLogin;     /* Login name.  NULL or "" if not logged in. */
  const char *zSSLIdentity;  /* Value of --ssl-identity option, filename of
                             ** SSL client identity */
1292
1293
1294
1295
1296
1297
1298

1299
1300
1301

1302
1303
1304
1305
1306
1307
1308
    zMode = PD("HTTPS","off");
    zCur = PD("SCRIPT_NAME","/");
    i = strlen(zCur);
    while( i>0 && zCur[i-1]=='/' ) i--;
    if( fossil_stricmp(zMode,"on")==0 ){
      g.zBaseURL = mprintf("https://%s%.*s", zHost, i, zCur);
      g.zTop = &g.zBaseURL[8+strlen(zHost)];

    }else{
      g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur);
      g.zTop = &g.zBaseURL[7+strlen(zHost)];

    }
  }
  if( db_is_writeable("repository") ){
    if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL)){
      db_multi_exec("INSERT INTO config(name,value,mtime)"
                    "VALUES('baseurl:%q',1,now())", g.zBaseURL);
    }else{







>



>







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
    zMode = PD("HTTPS","off");
    zCur = PD("SCRIPT_NAME","/");
    i = strlen(zCur);
    while( i>0 && zCur[i-1]=='/' ) i--;
    if( fossil_stricmp(zMode,"on")==0 ){
      g.zBaseURL = mprintf("https://%s%.*s", zHost, i, zCur);
      g.zTop = &g.zBaseURL[8+strlen(zHost)];
      g.zHttpsURL = g.zBaseURL;
    }else{
      g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur);
      g.zTop = &g.zBaseURL[7+strlen(zHost)];
      g.zHttpsURL = mprintf("https://%s%.*s", zHost, i, zCur);
    }
  }
  if( db_is_writeable("repository") ){
    if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL)){
      db_multi_exec("INSERT INTO config(name,value,mtime)"
                    "VALUES('baseurl:%q',1,now())", g.zBaseURL);
    }else{
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
}

/* If the CGI program contains one or more lines of the form
**
**    redirect:  repository-filename  http://hostname/path/%s
**
** then control jumps here.  Search each repository for an artifact ID
** that matches the "name" CGI parameter and for the first match,
** redirect to the corresponding URL with the "name" CGI parameter
** inserted.  Paint an error page if no match is found.
**
** If there is a line of the form:
**
**    redirect: * URL
**
** Then a redirect is made to URL if no match is found.  Otherwise a
** very primitive error message is returned.







|
|
|







1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
}

/* If the CGI program contains one or more lines of the form
**
**    redirect:  repository-filename  http://hostname/path/%s
**
** then control jumps here.  Search each repository for an artifact ID
** or ticket ID that matches the "name" CGI parameter and for the
** first match, redirect to the corresponding URL with the "name" CGI
** parameter inserted.  Paint an error page if no match is found.
**
** If there is a line of the form:
**
**    redirect: * URL
**
** Then a redirect is made to URL if no match is found.  Otherwise a
** very primitive error message is returned.
1724
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
  if( zName && validate16(zName, strlen(zName)) ){
    for(i=0; i<nRedirect; i++){
      if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
        zNotFound = azRedirect[i*2+1];
        continue;
      }
      db_open_repository(azRedirect[i*2]);
      if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){

        cgi_redirectf(azRedirect[i*2+1], zName);
        return;
      }
      db_close(1);
    }
  }
  if( zNotFound ){
    cgi_redirectf(zNotFound, zName);
  }else{
    @ <html>
    @ <head><title>No Such Object</title></head>
    @ <body>
    @ <p>No such object: <b>%h(zName)</b></p>
    @ </body>
    cgi_reply();







|
>
|






|







1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
  if( zName && validate16(zName, strlen(zName)) ){
    for(i=0; i<nRedirect; i++){
      if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
        zNotFound = azRedirect[i*2+1];
        continue;
      }
      db_open_repository(azRedirect[i*2]);
      if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'", zName) ||
	  db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
        cgi_redirectf(azRedirect[i*2+1] /*works-like:"%s"*/, zName);
        return;
      }
      db_close(1);
    }
  }
  if( zNotFound ){
    cgi_redirectf(zNotFound /*works-like:"%s"*/, zName);
  }else{
    @ <html>
    @ <head><title>No Such Object</title></head>
    @ <body>
    @ <p>No such object: <b>%h(zName)</b></p>
    @ </body>
    cgi_reply();
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
**   --files GLOB     comma-separate glob patterns for static file to serve
**   --baseurl URL    base URL (useful with reverse proxies)
**   --scgi           Interpret input as SCGI rather than HTTP
**
** See also: cgi, server, winsrv
*/
void cmd_http(void){
  const char *zIpAddr;
  const char *zNotFound;
  const char *zHost;
  const char *zAltBase;
  const char *zFileGlob;
  int useSCGI;

  /* The winhttp module passes the --files option as --files-urlenc with







|







1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
**   --files GLOB     comma-separate glob patterns for static file to serve
**   --baseurl URL    base URL (useful with reverse proxies)
**   --scgi           Interpret input as SCGI rather than HTTP
**
** See also: cgi, server, winsrv
*/
void cmd_http(void){
  const char *zIpAddr = 0;
  const char *zNotFound;
  const char *zHost;
  const char *zAltBase;
  const char *zFileGlob;
  int useSCGI;

  /* The winhttp module passes the --files option as --files-urlenc with
1955
1956
1957
1958
1959
1960
1961
1962



1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
  }
  zNotFound = find_option("notfound", 0, 1);
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
  useSCGI = find_option("scgi", 0, 0)!=0;
  zAltBase = find_option("baseurl", 0, 1);
  if( zAltBase ) set_base_url(zAltBase);
  if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");



  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
  g.cgiOutput = 1;

  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
    fossil_fatal("no repository specified");
  }
  g.fullHttpReply = 1;
  if( g.argc>=5 ){
    g.httpIn = fossil_fopen(g.argv[2], "rb");
    g.httpOut = fossil_fopen(g.argv[3], "wb");
    zIpAddr = g.argv[4];
    find_server_repository(0, 5);
  }else{
    g.httpIn = stdin;
    g.httpOut = stdout;
    zIpAddr = 0;
    find_server_repository(0, 2);
  }
  if( zIpAddr==0 ){
    zIpAddr = cgi_ssh_remote_addr(0);
    if( zIpAddr && zIpAddr[0] ){
      g.fSshClient |= CGI_SSH_CLIENT;
    }







|
>
>
>



















<







1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989

1990
1991
1992
1993
1994
1995
1996
  }
  zNotFound = find_option("notfound", 0, 1);
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
  useSCGI = find_option("scgi", 0, 0)!=0;
  zAltBase = find_option("baseurl", 0, 1);
  if( zAltBase ) set_base_url(zAltBase);
  if( find_option("https",0,0)!=0 ){
    zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
    cgi_replace_parameter("HTTPS","on");
  }
  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
  g.cgiOutput = 1;

  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
    fossil_fatal("no repository specified");
  }
  g.fullHttpReply = 1;
  if( g.argc>=5 ){
    g.httpIn = fossil_fopen(g.argv[2], "rb");
    g.httpOut = fossil_fopen(g.argv[3], "wb");
    zIpAddr = g.argv[4];
    find_server_repository(0, 5);
  }else{
    g.httpIn = stdin;
    g.httpOut = stdout;

    find_server_repository(0, 2);
  }
  if( zIpAddr==0 ){
    zIpAddr = cgi_ssh_remote_addr(0);
    if( zIpAddr && zIpAddr[0] ){
      g.fSshClient |= CGI_SSH_CLIENT;
    }
Changes to src/main.mk.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
#
##############################################################################
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
##############################################################################
#
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
# This file is included by primary Makefile.
#

XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR) -I$(OBJDIR)


SRC = \
  $(SRCDIR)/add.c \
  $(SRCDIR)/allrepo.c \
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \

  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \












|











>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#
##############################################################################
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
##############################################################################
#
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
# This file is included by primary Makefile.
#

XTCC = $(TCC) -I. -I$(SRCDIR) -I$(OBJDIR) $(TCCFLAGS) $(CFLAGS)


SRC = \
  $(SRCDIR)/add.c \
  $(SRCDIR)/allrepo.c \
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \
  $(SRCDIR)/builtin.c \
  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \
122
123
124
125
126
127
128



129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
  $(SRCDIR)/winfile.c \
  $(SRCDIR)/winhttp.c \
  $(SRCDIR)/wysiwyg.c \
  $(SRCDIR)/xfer.c \
  $(SRCDIR)/xfersetup.c \
  $(SRCDIR)/zip.c




TRANS_SRC = \
  $(OBJDIR)/add_.c \
  $(OBJDIR)/allrepo_.c \
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \

  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \







>
>
>









>







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  $(SRCDIR)/winfile.c \
  $(SRCDIR)/winhttp.c \
  $(SRCDIR)/wysiwyg.c \
  $(SRCDIR)/xfer.c \
  $(SRCDIR)/xfersetup.c \
  $(SRCDIR)/zip.c

EXTRA_FILES = \
  $(SRCDIR)/diff.tcl

TRANS_SRC = \
  $(OBJDIR)/add_.c \
  $(OBJDIR)/allrepo_.c \
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \
  $(OBJDIR)/builtin_.c \
  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \
244
245
246
247
248
249
250

251
252
253
254
255
256
257
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \

 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \







>







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \
 $(OBJDIR)/builtin.o \
 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \
358
359
360
361
362
363
364



365
366
367
368
369
370
371
372
373
374
375
376



377
378
379



380
381
382
383
384
385
386

all:	$(OBJDIR) $(APPNAME)

install:	$(APPNAME)
	mkdir -p $(INSTALLDIR)
	mv $(APPNAME) $(INSTALLDIR)




$(OBJDIR):
	-mkdir $(OBJDIR)

$(OBJDIR)/translate:	$(SRCDIR)/translate.c
	$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c

$(OBJDIR)/makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c

$(OBJDIR)/mkindex:	$(SRCDIR)/mkindex.c
	$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c




$(OBJDIR)/mkversion:	$(SRCDIR)/mkversion.c
	$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c




# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion







>
>
>












>
>
>



>
>
>







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

all:	$(OBJDIR) $(APPNAME)

install:	$(APPNAME)
	mkdir -p $(INSTALLDIR)
	mv $(APPNAME) $(INSTALLDIR)

codecheck:	$(TRANS_SRC) $(OBJDIR)/codecheck1
	$(OBJDIR)/codecheck1 $(TRANS_SRC)

$(OBJDIR):
	-mkdir $(OBJDIR)

$(OBJDIR)/translate:	$(SRCDIR)/translate.c
	$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c

$(OBJDIR)/makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c

$(OBJDIR)/mkindex:	$(SRCDIR)/mkindex.c
	$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c

$(OBJDIR)/mkbuiltin:	$(SRCDIR)/mkbuiltin.c
	$(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c

$(OBJDIR)/mkversion:	$(SRCDIR)/mkversion.c
	$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c

$(OBJDIR)/codecheck1:	$(SRCDIR)/codecheck1.c
	$(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c

# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449




450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
 $(OBJDIR)/shell.o \
 $(OBJDIR)/th.o \
 $(OBJDIR)/th_lang.o \
 $(OBJDIR)/th_tcl.o \
 $(OBJDIR)/cson_amalgamation.o


$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)

	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(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:
	# noop

clean:
	rm -rf $(OBJDIR)/* $(APPNAME)


$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
	$(OBJDIR)/mkindex $(TRANS_SRC) >$@




$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
	$(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
	$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
	$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
	$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
	$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
	$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
	$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
	$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \

	$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
	$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
	$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
	$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
	$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
	$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
	$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \







|
>














>
>
>
>
|








>







443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
 $(OBJDIR)/shell.o \
 $(OBJDIR)/th.o \
 $(OBJDIR)/th_lang.o \
 $(OBJDIR)/th_tcl.o \
 $(OBJDIR)/cson_amalgamation.o


$(APPNAME):	$(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
	$(OBJDIR)/codecheck1 $(TRANS_SRC)
	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(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:
	# noop

clean:
	rm -rf $(OBJDIR)/* $(APPNAME)


$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
	$(OBJDIR)/mkindex $(TRANS_SRC) >$@

$(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES)
	$(OBJDIR)/mkbuiltin $(EXTRA_FILES) >$@

$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
	$(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
	$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
	$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
	$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
	$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
	$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
	$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
	$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
	$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
	$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
	$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
	$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
	$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
	$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
	$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
	$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \
563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580
581
582

583
584
585
586
587
588
589

590
591
592
593
594
595
596

597
598
599
600
601
602
603

604
605
606
607
608
609
610

611
612
613
614
615
616
617

618
619
620
621
622
623
624









625
626
627
628
629
630
631

632
633
634
635
636
637
638

639
640
641
642
643
644
645

646
647
648
649
650
651
652

653
654
655
656
657
658
659

660
661
662
663
664
665
666

667
668
669
670
671
672
673

674
675
676
677
678
679
680

681
682
683
684
685
686
687

688
689
690
691
692
693
694

695
696
697
698
699
700
701

702
703
704
705
706
707
708

709
710
711
712
713
714
715

716
717
718
719
720
721
722

723
724
725
726
727
728
729

730
731
732
733
734
735
736

737
738
739
740
741
742
743

744
745
746
747
748
749
750

751
752
753
754
755
756
757

758
759
760
761
762
763
764

765
766
767
768
769
770
771

772
773
774
775
776
777
778

779
780
781
782
783
784
785

786
787
788
789
790
791
792

793
794
795
796
797
798
799

800
801
802
803
804
805
806

807
808
809
810
811
812
813

814
815
816
817
818
819
820

821
822
823
824
825
826
827

828
829
830
831
832
833
834

835
836
837
838
839
840
841

842
843
844
845
846
847
848

849
850
851
852
853
854
855

856
857
858
859
860
861
862

863
864
865
866
867
868
869

870
871
872
873
874
875
876

877
878
879
880
881
882
883

884
885
886
887
888
889
890

891
892
893
894
895
896
897

898
899
900
901
902
903
904

905
906
907
908
909
910
911

912
913
914
915
916
917
918

919
920
921
922
923
924
925

926
927
928
929
930
931
932

933
934
935
936
937
938
939

940
941
942
943
944
945
946

947
948
949
950
951
952
953

954
955
956
957
958
959
960

961
962
963
964
965
966
967

968
969
970
971
972
973
974

975
976
977
978
979
980
981

982
983
984
985
986
987
988

989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009

1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037

1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051

1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079

1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100

1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121

1122
1123
1124
1125
1126
1127
1128

1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156

1157
1158
1159
1160
1161
1162
1163

1164
1165
1166
1167
1168
1169
1170

1171
1172
1173
1174
1175
1176
1177

1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205

1206
1207
1208
1209
1210
1211
1212

1213
1214
1215
1216
1217
1218
1219

1220
1221
1222
1223
1224
1225
1226

1227
1228
1229
1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268

1269
1270
1271
1272
1273
1274
1275

1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310

1311
1312
1313
1314
1315
1316
1317

1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331

1332
1333
1334
1335
1336
1337
1338

1339
1340
1341
1342
1343
1344
1345

1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
	$(SRCDIR)/th.h \
	$(OBJDIR)/VERSION.h
	touch $(OBJDIR)/headers
$(OBJDIR)/headers: Makefile
$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
Makefile:
$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c

$(OBJDIR)/add.o:	$(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c

$(OBJDIR)/add.h:	$(OBJDIR)/headers

$(OBJDIR)/allrepo_.c:	$(SRCDIR)/allrepo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/allrepo.c >$(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.o:	$(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.h:	$(OBJDIR)/headers

$(OBJDIR)/attach_.c:	$(SRCDIR)/attach.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/attach.c >$(OBJDIR)/attach_.c

$(OBJDIR)/attach.o:	$(OBJDIR)/attach_.c $(OBJDIR)/attach.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/attach.o -c $(OBJDIR)/attach_.c

$(OBJDIR)/attach.h:	$(OBJDIR)/headers

$(OBJDIR)/bag_.c:	$(SRCDIR)/bag.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/bag.c >$(OBJDIR)/bag_.c

$(OBJDIR)/bag.o:	$(OBJDIR)/bag_.c $(OBJDIR)/bag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c $(OBJDIR)/bag_.c

$(OBJDIR)/bag.h:	$(OBJDIR)/headers

$(OBJDIR)/bisect_.c:	$(SRCDIR)/bisect.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/bisect.c >$(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.o:	$(OBJDIR)/bisect_.c $(OBJDIR)/bisect.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bisect.o -c $(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.h:	$(OBJDIR)/headers

$(OBJDIR)/blob_.c:	$(SRCDIR)/blob.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/blob.c >$(OBJDIR)/blob_.c

$(OBJDIR)/blob.o:	$(OBJDIR)/blob_.c $(OBJDIR)/blob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c $(OBJDIR)/blob_.c

$(OBJDIR)/blob.h:	$(OBJDIR)/headers

$(OBJDIR)/branch_.c:	$(SRCDIR)/branch.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/branch.c >$(OBJDIR)/branch_.c

$(OBJDIR)/branch.o:	$(OBJDIR)/branch_.c $(OBJDIR)/branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c $(OBJDIR)/branch_.c

$(OBJDIR)/branch.h:	$(OBJDIR)/headers

$(OBJDIR)/browse_.c:	$(SRCDIR)/browse.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/browse.c >$(OBJDIR)/browse_.c

$(OBJDIR)/browse.o:	$(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c

$(OBJDIR)/browse.h:	$(OBJDIR)/headers









$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

$(OBJDIR)/cache.h:	$(OBJDIR)/headers

$(OBJDIR)/captcha_.c:	$(SRCDIR)/captcha.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/captcha.c >$(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.o:	$(OBJDIR)/captcha_.c $(OBJDIR)/captcha.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c $(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.h:	$(OBJDIR)/headers

$(OBJDIR)/cgi_.c:	$(SRCDIR)/cgi.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/cgi.c >$(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.o:	$(OBJDIR)/cgi_.c $(OBJDIR)/cgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c $(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.h:	$(OBJDIR)/headers

$(OBJDIR)/checkin_.c:	$(SRCDIR)/checkin.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/checkin.c >$(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.o:	$(OBJDIR)/checkin_.c $(OBJDIR)/checkin.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c $(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.h:	$(OBJDIR)/headers

$(OBJDIR)/checkout_.c:	$(SRCDIR)/checkout.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/checkout.c >$(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.o:	$(OBJDIR)/checkout_.c $(OBJDIR)/checkout.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c $(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.h:	$(OBJDIR)/headers

$(OBJDIR)/clearsign_.c:	$(SRCDIR)/clearsign.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/clearsign.c >$(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.o:	$(OBJDIR)/clearsign_.c $(OBJDIR)/clearsign.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c $(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.h:	$(OBJDIR)/headers

$(OBJDIR)/clone_.c:	$(SRCDIR)/clone.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/clone.c >$(OBJDIR)/clone_.c

$(OBJDIR)/clone.o:	$(OBJDIR)/clone_.c $(OBJDIR)/clone.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c $(OBJDIR)/clone_.c

$(OBJDIR)/clone.h:	$(OBJDIR)/headers

$(OBJDIR)/comformat_.c:	$(SRCDIR)/comformat.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/comformat.c >$(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.o:	$(OBJDIR)/comformat_.c $(OBJDIR)/comformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c $(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.h:	$(OBJDIR)/headers

$(OBJDIR)/configure_.c:	$(SRCDIR)/configure.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/configure.c >$(OBJDIR)/configure_.c

$(OBJDIR)/configure.o:	$(OBJDIR)/configure_.c $(OBJDIR)/configure.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c $(OBJDIR)/configure_.c

$(OBJDIR)/configure.h:	$(OBJDIR)/headers

$(OBJDIR)/content_.c:	$(SRCDIR)/content.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/content.c >$(OBJDIR)/content_.c

$(OBJDIR)/content.o:	$(OBJDIR)/content_.c $(OBJDIR)/content.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c $(OBJDIR)/content_.c

$(OBJDIR)/content.h:	$(OBJDIR)/headers

$(OBJDIR)/db_.c:	$(SRCDIR)/db.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/db.c >$(OBJDIR)/db_.c

$(OBJDIR)/db.o:	$(OBJDIR)/db_.c $(OBJDIR)/db.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c $(OBJDIR)/db_.c

$(OBJDIR)/db.h:	$(OBJDIR)/headers

$(OBJDIR)/delta_.c:	$(SRCDIR)/delta.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/delta.c >$(OBJDIR)/delta_.c

$(OBJDIR)/delta.o:	$(OBJDIR)/delta_.c $(OBJDIR)/delta.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c $(OBJDIR)/delta_.c

$(OBJDIR)/delta.h:	$(OBJDIR)/headers

$(OBJDIR)/deltacmd_.c:	$(SRCDIR)/deltacmd.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/deltacmd.c >$(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.o:	$(OBJDIR)/deltacmd_.c $(OBJDIR)/deltacmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c $(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.h:	$(OBJDIR)/headers

$(OBJDIR)/descendants_.c:	$(SRCDIR)/descendants.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/descendants.c >$(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.o:	$(OBJDIR)/descendants_.c $(OBJDIR)/descendants.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c $(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.h:	$(OBJDIR)/headers

$(OBJDIR)/diff_.c:	$(SRCDIR)/diff.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/diff.c >$(OBJDIR)/diff_.c

$(OBJDIR)/diff.o:	$(OBJDIR)/diff_.c $(OBJDIR)/diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c $(OBJDIR)/diff_.c

$(OBJDIR)/diff.h:	$(OBJDIR)/headers

$(OBJDIR)/diffcmd_.c:	$(SRCDIR)/diffcmd.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/diffcmd.c >$(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.o:	$(OBJDIR)/diffcmd_.c $(OBJDIR)/diffcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c $(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/doc_.c:	$(SRCDIR)/doc.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/doc.c >$(OBJDIR)/doc_.c

$(OBJDIR)/doc.o:	$(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c

$(OBJDIR)/doc.h:	$(OBJDIR)/headers

$(OBJDIR)/encode_.c:	$(SRCDIR)/encode.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/encode.c >$(OBJDIR)/encode_.c

$(OBJDIR)/encode.o:	$(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c

$(OBJDIR)/encode.h:	$(OBJDIR)/headers

$(OBJDIR)/event_.c:	$(SRCDIR)/event.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/event.c >$(OBJDIR)/event_.c

$(OBJDIR)/event.o:	$(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/event.o -c $(OBJDIR)/event_.c

$(OBJDIR)/event.h:	$(OBJDIR)/headers

$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/export.c >$(OBJDIR)/export_.c

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/file.c >$(OBJDIR)/file_.c

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

$(OBJDIR)/file.h:	$(OBJDIR)/headers

$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/finfo.c >$(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/fusefs.c >$(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.h:	$(OBJDIR)/headers

$(OBJDIR)/glob_.c:	$(SRCDIR)/glob.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/glob.c >$(OBJDIR)/glob_.c

$(OBJDIR)/glob.o:	$(OBJDIR)/glob_.c $(OBJDIR)/glob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/glob.o -c $(OBJDIR)/glob_.c

$(OBJDIR)/glob.h:	$(OBJDIR)/headers

$(OBJDIR)/graph_.c:	$(SRCDIR)/graph.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/graph.c >$(OBJDIR)/graph_.c

$(OBJDIR)/graph.o:	$(OBJDIR)/graph_.c $(OBJDIR)/graph.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c $(OBJDIR)/graph_.c

$(OBJDIR)/graph.h:	$(OBJDIR)/headers

$(OBJDIR)/gzip_.c:	$(SRCDIR)/gzip.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/gzip.c >$(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.o:	$(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.h:	$(OBJDIR)/headers

$(OBJDIR)/http_.c:	$(SRCDIR)/http.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http.c >$(OBJDIR)/http_.c

$(OBJDIR)/http.o:	$(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c

$(OBJDIR)/http.h:	$(OBJDIR)/headers

$(OBJDIR)/http_socket_.c:	$(SRCDIR)/http_socket.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http_socket.c >$(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.o:	$(OBJDIR)/http_socket_.c $(OBJDIR)/http_socket.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c $(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.h:	$(OBJDIR)/headers

$(OBJDIR)/http_ssl_.c:	$(SRCDIR)/http_ssl.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http_ssl.c >$(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.o:	$(OBJDIR)/http_ssl_.c $(OBJDIR)/http_ssl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_ssl.o -c $(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.h:	$(OBJDIR)/headers

$(OBJDIR)/http_transport_.c:	$(SRCDIR)/http_transport.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http_transport.c >$(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.o:	$(OBJDIR)/http_transport_.c $(OBJDIR)/http_transport.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c $(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.h:	$(OBJDIR)/headers

$(OBJDIR)/import_.c:	$(SRCDIR)/import.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/import.c >$(OBJDIR)/import_.c

$(OBJDIR)/import.o:	$(OBJDIR)/import_.c $(OBJDIR)/import.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/import.o -c $(OBJDIR)/import_.c

$(OBJDIR)/import.h:	$(OBJDIR)/headers

$(OBJDIR)/info_.c:	$(SRCDIR)/info.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/info.c >$(OBJDIR)/info_.c

$(OBJDIR)/info.o:	$(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c

$(OBJDIR)/info.h:	$(OBJDIR)/headers

$(OBJDIR)/json_.c:	$(SRCDIR)/json.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json.c >$(OBJDIR)/json_.c

$(OBJDIR)/json.o:	$(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c

$(OBJDIR)/json.h:	$(OBJDIR)/headers

$(OBJDIR)/json_artifact_.c:	$(SRCDIR)/json_artifact.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.o:	$(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.h:	$(OBJDIR)/headers

$(OBJDIR)/json_branch_.c:	$(SRCDIR)/json_branch.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.o:	$(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.h:	$(OBJDIR)/headers

$(OBJDIR)/json_config_.c:	$(SRCDIR)/json_config.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_config.c >$(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.o:	$(OBJDIR)/json_config_.c $(OBJDIR)/json_config.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_config.o -c $(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.h:	$(OBJDIR)/headers

$(OBJDIR)/json_diff_.c:	$(SRCDIR)/json_diff.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.o:	$(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.h:	$(OBJDIR)/headers

$(OBJDIR)/json_dir_.c:	$(SRCDIR)/json_dir.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_dir.c >$(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.o:	$(OBJDIR)/json_dir_.c $(OBJDIR)/json_dir.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_dir.o -c $(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.h:	$(OBJDIR)/headers

$(OBJDIR)/json_finfo_.c:	$(SRCDIR)/json_finfo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_finfo.c >$(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.o:	$(OBJDIR)/json_finfo_.c $(OBJDIR)/json_finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_finfo.o -c $(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/json_login_.c:	$(SRCDIR)/json_login.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.o:	$(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.h:	$(OBJDIR)/headers

$(OBJDIR)/json_query_.c:	$(SRCDIR)/json_query.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.o:	$(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.h:	$(OBJDIR)/headers

$(OBJDIR)/json_report_.c:	$(SRCDIR)/json_report.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.o:	$(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.h:	$(OBJDIR)/headers

$(OBJDIR)/json_status_.c:	$(SRCDIR)/json_status.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_status.c >$(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.o:	$(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.h:	$(OBJDIR)/headers

$(OBJDIR)/json_tag_.c:	$(SRCDIR)/json_tag.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.o:	$(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.h:	$(OBJDIR)/headers

$(OBJDIR)/json_timeline_.c:	$(SRCDIR)/json_timeline.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.o:	$(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/json_user_.c:	$(SRCDIR)/json_user.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.o:	$(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.h:	$(OBJDIR)/headers

$(OBJDIR)/json_wiki_.c:	$(SRCDIR)/json_wiki.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.o:	$(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/leaf_.c:	$(SRCDIR)/leaf.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.o:	$(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.h:	$(OBJDIR)/headers

$(OBJDIR)/loadctrl_.c:	$(SRCDIR)/loadctrl.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/loadctrl.c >$(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.o:	$(OBJDIR)/loadctrl_.c $(OBJDIR)/loadctrl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/loadctrl.o -c $(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.h:	$(OBJDIR)/headers

$(OBJDIR)/login_.c:	$(SRCDIR)/login.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/login.c >$(OBJDIR)/login_.c

$(OBJDIR)/login.o:	$(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c

$(OBJDIR)/login.h:	$(OBJDIR)/headers

$(OBJDIR)/lookslike_.c:	$(SRCDIR)/lookslike.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.o:	$(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.h:	$(OBJDIR)/headers

$(OBJDIR)/main_.c:	$(SRCDIR)/main.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/main.c >$(OBJDIR)/main_.c

$(OBJDIR)/main.o:	$(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c

$(OBJDIR)/main.h:	$(OBJDIR)/headers

$(OBJDIR)/manifest_.c:	$(SRCDIR)/manifest.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/manifest.c >$(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.o:	$(OBJDIR)/manifest_.c $(OBJDIR)/manifest.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c $(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_.c:	$(SRCDIR)/markdown.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/markdown.c >$(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.o:	$(OBJDIR)/markdown_.c $(OBJDIR)/markdown.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown.o -c $(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_html_.c:	$(SRCDIR)/markdown_html.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/markdown_html.c >$(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.o:	$(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.h:	$(OBJDIR)/headers

$(OBJDIR)/md5_.c:	$(SRCDIR)/md5.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/md5.c >$(OBJDIR)/md5_.c

$(OBJDIR)/md5.o:	$(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c

$(OBJDIR)/md5.h:	$(OBJDIR)/headers

$(OBJDIR)/merge_.c:	$(SRCDIR)/merge.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/merge.c >$(OBJDIR)/merge_.c

$(OBJDIR)/merge.o:	$(OBJDIR)/merge_.c $(OBJDIR)/merge.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c $(OBJDIR)/merge_.c

$(OBJDIR)/merge.h:	$(OBJDIR)/headers

$(OBJDIR)/merge3_.c:	$(SRCDIR)/merge3.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/merge3.c >$(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.o:	$(OBJDIR)/merge3_.c $(OBJDIR)/merge3.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c $(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.h:	$(OBJDIR)/headers

$(OBJDIR)/moderate_.c:	$(SRCDIR)/moderate.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/moderate.c >$(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.o:	$(OBJDIR)/moderate_.c $(OBJDIR)/moderate.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/moderate.o -c $(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.h:	$(OBJDIR)/headers

$(OBJDIR)/name_.c:	$(SRCDIR)/name.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/name.c >$(OBJDIR)/name_.c

$(OBJDIR)/name.o:	$(OBJDIR)/name_.c $(OBJDIR)/name.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c $(OBJDIR)/name_.c

$(OBJDIR)/name.h:	$(OBJDIR)/headers

$(OBJDIR)/path_.c:	$(SRCDIR)/path.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/path.c >$(OBJDIR)/path_.c

$(OBJDIR)/path.o:	$(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c

$(OBJDIR)/path.h:	$(OBJDIR)/headers

$(OBJDIR)/pivot_.c:	$(SRCDIR)/pivot.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/pivot.c >$(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.o:	$(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.h:	$(OBJDIR)/headers

$(OBJDIR)/popen_.c:	$(SRCDIR)/popen.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/popen.c >$(OBJDIR)/popen_.c

$(OBJDIR)/popen.o:	$(OBJDIR)/popen_.c $(OBJDIR)/popen.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/popen.o -c $(OBJDIR)/popen_.c

$(OBJDIR)/popen.h:	$(OBJDIR)/headers

$(OBJDIR)/pqueue_.c:	$(SRCDIR)/pqueue.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/pqueue.c >$(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.o:	$(OBJDIR)/pqueue_.c $(OBJDIR)/pqueue.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c $(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.h:	$(OBJDIR)/headers

$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/printf.c >$(OBJDIR)/printf_.c

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/rebuild.c >$(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.h:	$(OBJDIR)/headers

$(OBJDIR)/regexp_.c:	$(SRCDIR)/regexp.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.o:	$(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.h:	$(OBJDIR)/headers

$(OBJDIR)/report_.c:	$(SRCDIR)/report.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/report.c >$(OBJDIR)/report_.c

$(OBJDIR)/report.o:	$(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c

$(OBJDIR)/report.h:	$(OBJDIR)/headers

$(OBJDIR)/rss_.c:	$(SRCDIR)/rss.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/rss.c >$(OBJDIR)/rss_.c

$(OBJDIR)/rss.o:	$(OBJDIR)/rss_.c $(OBJDIR)/rss.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c $(OBJDIR)/rss_.c

$(OBJDIR)/rss.h:	$(OBJDIR)/headers

$(OBJDIR)/schema_.c:	$(SRCDIR)/schema.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/schema.c >$(OBJDIR)/schema_.c

$(OBJDIR)/schema.o:	$(OBJDIR)/schema_.c $(OBJDIR)/schema.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c $(OBJDIR)/schema_.c

$(OBJDIR)/schema.h:	$(OBJDIR)/headers

$(OBJDIR)/search_.c:	$(SRCDIR)/search.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/search.c >$(OBJDIR)/search_.c

$(OBJDIR)/search.o:	$(OBJDIR)/search_.c $(OBJDIR)/search.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c $(OBJDIR)/search_.c

$(OBJDIR)/search.h:	$(OBJDIR)/headers

$(OBJDIR)/setup_.c:	$(SRCDIR)/setup.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/setup.c >$(OBJDIR)/setup_.c

$(OBJDIR)/setup.o:	$(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c

$(OBJDIR)/setup.h:	$(OBJDIR)/headers

$(OBJDIR)/sha1_.c:	$(SRCDIR)/sha1.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/sha1.c >$(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.o:	$(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.h:	$(OBJDIR)/headers

$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/shun.c >$(OBJDIR)/shun_.c

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/skins.c >$(OBJDIR)/skins_.c

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

$(OBJDIR)/skins.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlcmd_.c:	$(SRCDIR)/sqlcmd.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/sqlcmd.c >$(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.o:	$(OBJDIR)/sqlcmd_.c $(OBJDIR)/sqlcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sqlcmd.o -c $(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/stash_.c:	$(SRCDIR)/stash.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/stash.c >$(OBJDIR)/stash_.c

$(OBJDIR)/stash.o:	$(OBJDIR)/stash_.c $(OBJDIR)/stash.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stash.o -c $(OBJDIR)/stash_.c

$(OBJDIR)/stash.h:	$(OBJDIR)/headers

$(OBJDIR)/stat_.c:	$(SRCDIR)/stat.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/stat.c >$(OBJDIR)/stat_.c

$(OBJDIR)/stat.o:	$(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c

$(OBJDIR)/stat.h:	$(OBJDIR)/headers

$(OBJDIR)/style_.c:	$(SRCDIR)/style.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/style.c >$(OBJDIR)/style_.c

$(OBJDIR)/style.o:	$(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c $(OBJDIR)/style_.c

$(OBJDIR)/style.h:	$(OBJDIR)/headers

$(OBJDIR)/sync_.c:	$(SRCDIR)/sync.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/sync.c >$(OBJDIR)/sync_.c

$(OBJDIR)/sync.o:	$(OBJDIR)/sync_.c $(OBJDIR)/sync.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c $(OBJDIR)/sync_.c

$(OBJDIR)/sync.h:	$(OBJDIR)/headers

$(OBJDIR)/tag_.c:	$(SRCDIR)/tag.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tag.c >$(OBJDIR)/tag_.c

$(OBJDIR)/tag.o:	$(OBJDIR)/tag_.c $(OBJDIR)/tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c $(OBJDIR)/tag_.c

$(OBJDIR)/tag.h:	$(OBJDIR)/headers

$(OBJDIR)/tar_.c:	$(SRCDIR)/tar.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tar.c >$(OBJDIR)/tar_.c

$(OBJDIR)/tar.o:	$(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c

$(OBJDIR)/tar.h:	$(OBJDIR)/headers

$(OBJDIR)/th_main_.c:	$(SRCDIR)/th_main.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/th_main.c >$(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.o:	$(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.h:	$(OBJDIR)/headers

$(OBJDIR)/timeline_.c:	$(SRCDIR)/timeline.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/timeline.c >$(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.o:	$(OBJDIR)/timeline_.c $(OBJDIR)/timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c $(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/tkt_.c:	$(SRCDIR)/tkt.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tkt.c >$(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.o:	$(OBJDIR)/tkt_.c $(OBJDIR)/tkt.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c $(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.h:	$(OBJDIR)/headers

$(OBJDIR)/tktsetup_.c:	$(SRCDIR)/tktsetup.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tktsetup.c >$(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.o:	$(OBJDIR)/tktsetup_.c $(OBJDIR)/tktsetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c $(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.h:	$(OBJDIR)/headers

$(OBJDIR)/undo_.c:	$(SRCDIR)/undo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/undo.c >$(OBJDIR)/undo_.c

$(OBJDIR)/undo.o:	$(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c

$(OBJDIR)/undo.h:	$(OBJDIR)/headers

$(OBJDIR)/unicode_.c:	$(SRCDIR)/unicode.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.o:	$(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.h:	$(OBJDIR)/headers

$(OBJDIR)/update_.c:	$(SRCDIR)/update.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/update.c >$(OBJDIR)/update_.c

$(OBJDIR)/update.o:	$(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c

$(OBJDIR)/update.h:	$(OBJDIR)/headers

$(OBJDIR)/url_.c:	$(SRCDIR)/url.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/url.c >$(OBJDIR)/url_.c

$(OBJDIR)/url.o:	$(OBJDIR)/url_.c $(OBJDIR)/url.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c $(OBJDIR)/url_.c

$(OBJDIR)/url.h:	$(OBJDIR)/headers

$(OBJDIR)/user_.c:	$(SRCDIR)/user.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/user.c >$(OBJDIR)/user_.c

$(OBJDIR)/user.o:	$(OBJDIR)/user_.c $(OBJDIR)/user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c $(OBJDIR)/user_.c

$(OBJDIR)/user.h:	$(OBJDIR)/headers

$(OBJDIR)/utf8_.c:	$(SRCDIR)/utf8.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/utf8.c >$(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.o:	$(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.h:	$(OBJDIR)/headers

$(OBJDIR)/util_.c:	$(SRCDIR)/util.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/util.c >$(OBJDIR)/util_.c

$(OBJDIR)/util.o:	$(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c

$(OBJDIR)/util.h:	$(OBJDIR)/headers

$(OBJDIR)/verify_.c:	$(SRCDIR)/verify.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/verify.c >$(OBJDIR)/verify_.c

$(OBJDIR)/verify.o:	$(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c $(OBJDIR)/verify_.c

$(OBJDIR)/verify.h:	$(OBJDIR)/headers

$(OBJDIR)/vfile_.c:	$(SRCDIR)/vfile.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/vfile.c >$(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.o:	$(OBJDIR)/vfile_.c $(OBJDIR)/vfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c $(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.h:	$(OBJDIR)/headers

$(OBJDIR)/wiki_.c:	$(SRCDIR)/wiki.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/wiki.c >$(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.o:	$(OBJDIR)/wiki_.c $(OBJDIR)/wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c $(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/wikiformat_.c:	$(SRCDIR)/wikiformat.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/wikiformat.c >$(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.o:	$(OBJDIR)/wikiformat_.c $(OBJDIR)/wikiformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c $(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.h:	$(OBJDIR)/headers

$(OBJDIR)/winfile_.c:	$(SRCDIR)/winfile.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/winfile.c >$(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.o:	$(OBJDIR)/winfile_.c $(OBJDIR)/winfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winfile.o -c $(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.h:	$(OBJDIR)/headers

$(OBJDIR)/winhttp_.c:	$(SRCDIR)/winhttp.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/winhttp.c >$(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.o:	$(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.h:	$(OBJDIR)/headers

$(OBJDIR)/wysiwyg_.c:	$(SRCDIR)/wysiwyg.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/wysiwyg.c >$(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.o:	$(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.h:	$(OBJDIR)/headers

$(OBJDIR)/xfer_.c:	$(SRCDIR)/xfer.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/xfer.c >$(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.o:	$(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.h:	$(OBJDIR)/headers

$(OBJDIR)/xfersetup_.c:	$(SRCDIR)/xfersetup.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/xfersetup.c >$(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.o:	$(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.h:	$(OBJDIR)/headers

$(OBJDIR)/zip_.c:	$(SRCDIR)/zip.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/zip.c >$(OBJDIR)/zip_.c

$(OBJDIR)/zip.o:	$(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
	$(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o

$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o


$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $(OBJDIR)/miniz.o

$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o

#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#

.PHONY: all install test clean








|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>
>
>
>
>
>
>
>
>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|





>

|


|


|


|


|



|


|








584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
	$(SRCDIR)/th.h \
	$(OBJDIR)/VERSION.h
	touch $(OBJDIR)/headers
$(OBJDIR)/headers: Makefile
$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
Makefile:
$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/add.c >$@

$(OBJDIR)/add.o:	$(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c

$(OBJDIR)/add.h:	$(OBJDIR)/headers

$(OBJDIR)/allrepo_.c:	$(SRCDIR)/allrepo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/allrepo.c >$@

$(OBJDIR)/allrepo.o:	$(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.h:	$(OBJDIR)/headers

$(OBJDIR)/attach_.c:	$(SRCDIR)/attach.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/attach.c >$@

$(OBJDIR)/attach.o:	$(OBJDIR)/attach_.c $(OBJDIR)/attach.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/attach.o -c $(OBJDIR)/attach_.c

$(OBJDIR)/attach.h:	$(OBJDIR)/headers

$(OBJDIR)/bag_.c:	$(SRCDIR)/bag.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/bag.c >$@

$(OBJDIR)/bag.o:	$(OBJDIR)/bag_.c $(OBJDIR)/bag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c $(OBJDIR)/bag_.c

$(OBJDIR)/bag.h:	$(OBJDIR)/headers

$(OBJDIR)/bisect_.c:	$(SRCDIR)/bisect.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/bisect.c >$@

$(OBJDIR)/bisect.o:	$(OBJDIR)/bisect_.c $(OBJDIR)/bisect.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bisect.o -c $(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.h:	$(OBJDIR)/headers

$(OBJDIR)/blob_.c:	$(SRCDIR)/blob.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/blob.c >$@

$(OBJDIR)/blob.o:	$(OBJDIR)/blob_.c $(OBJDIR)/blob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c $(OBJDIR)/blob_.c

$(OBJDIR)/blob.h:	$(OBJDIR)/headers

$(OBJDIR)/branch_.c:	$(SRCDIR)/branch.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/branch.c >$@

$(OBJDIR)/branch.o:	$(OBJDIR)/branch_.c $(OBJDIR)/branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c $(OBJDIR)/branch_.c

$(OBJDIR)/branch.h:	$(OBJDIR)/headers

$(OBJDIR)/browse_.c:	$(SRCDIR)/browse.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/browse.c >$@

$(OBJDIR)/browse.o:	$(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c

$(OBJDIR)/browse.h:	$(OBJDIR)/headers

$(OBJDIR)/builtin_.c:	$(SRCDIR)/builtin.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/builtin.c >$@

$(OBJDIR)/builtin.o:	$(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c

$(OBJDIR)/builtin.h:	$(OBJDIR)/headers

$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/cache.c >$@

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

$(OBJDIR)/cache.h:	$(OBJDIR)/headers

$(OBJDIR)/captcha_.c:	$(SRCDIR)/captcha.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/captcha.c >$@

$(OBJDIR)/captcha.o:	$(OBJDIR)/captcha_.c $(OBJDIR)/captcha.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c $(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.h:	$(OBJDIR)/headers

$(OBJDIR)/cgi_.c:	$(SRCDIR)/cgi.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/cgi.c >$@

$(OBJDIR)/cgi.o:	$(OBJDIR)/cgi_.c $(OBJDIR)/cgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c $(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.h:	$(OBJDIR)/headers

$(OBJDIR)/checkin_.c:	$(SRCDIR)/checkin.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/checkin.c >$@

$(OBJDIR)/checkin.o:	$(OBJDIR)/checkin_.c $(OBJDIR)/checkin.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c $(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.h:	$(OBJDIR)/headers

$(OBJDIR)/checkout_.c:	$(SRCDIR)/checkout.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/checkout.c >$@

$(OBJDIR)/checkout.o:	$(OBJDIR)/checkout_.c $(OBJDIR)/checkout.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c $(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.h:	$(OBJDIR)/headers

$(OBJDIR)/clearsign_.c:	$(SRCDIR)/clearsign.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/clearsign.c >$@

$(OBJDIR)/clearsign.o:	$(OBJDIR)/clearsign_.c $(OBJDIR)/clearsign.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c $(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.h:	$(OBJDIR)/headers

$(OBJDIR)/clone_.c:	$(SRCDIR)/clone.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/clone.c >$@

$(OBJDIR)/clone.o:	$(OBJDIR)/clone_.c $(OBJDIR)/clone.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c $(OBJDIR)/clone_.c

$(OBJDIR)/clone.h:	$(OBJDIR)/headers

$(OBJDIR)/comformat_.c:	$(SRCDIR)/comformat.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/comformat.c >$@

$(OBJDIR)/comformat.o:	$(OBJDIR)/comformat_.c $(OBJDIR)/comformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c $(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.h:	$(OBJDIR)/headers

$(OBJDIR)/configure_.c:	$(SRCDIR)/configure.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/configure.c >$@

$(OBJDIR)/configure.o:	$(OBJDIR)/configure_.c $(OBJDIR)/configure.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c $(OBJDIR)/configure_.c

$(OBJDIR)/configure.h:	$(OBJDIR)/headers

$(OBJDIR)/content_.c:	$(SRCDIR)/content.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/content.c >$@

$(OBJDIR)/content.o:	$(OBJDIR)/content_.c $(OBJDIR)/content.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c $(OBJDIR)/content_.c

$(OBJDIR)/content.h:	$(OBJDIR)/headers

$(OBJDIR)/db_.c:	$(SRCDIR)/db.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/db.c >$@

$(OBJDIR)/db.o:	$(OBJDIR)/db_.c $(OBJDIR)/db.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c $(OBJDIR)/db_.c

$(OBJDIR)/db.h:	$(OBJDIR)/headers

$(OBJDIR)/delta_.c:	$(SRCDIR)/delta.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/delta.c >$@

$(OBJDIR)/delta.o:	$(OBJDIR)/delta_.c $(OBJDIR)/delta.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c $(OBJDIR)/delta_.c

$(OBJDIR)/delta.h:	$(OBJDIR)/headers

$(OBJDIR)/deltacmd_.c:	$(SRCDIR)/deltacmd.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/deltacmd.c >$@

$(OBJDIR)/deltacmd.o:	$(OBJDIR)/deltacmd_.c $(OBJDIR)/deltacmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c $(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.h:	$(OBJDIR)/headers

$(OBJDIR)/descendants_.c:	$(SRCDIR)/descendants.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/descendants.c >$@

$(OBJDIR)/descendants.o:	$(OBJDIR)/descendants_.c $(OBJDIR)/descendants.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c $(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.h:	$(OBJDIR)/headers

$(OBJDIR)/diff_.c:	$(SRCDIR)/diff.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/diff.c >$@

$(OBJDIR)/diff.o:	$(OBJDIR)/diff_.c $(OBJDIR)/diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c $(OBJDIR)/diff_.c

$(OBJDIR)/diff.h:	$(OBJDIR)/headers

$(OBJDIR)/diffcmd_.c:	$(SRCDIR)/diffcmd.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/diffcmd.c >$@

$(OBJDIR)/diffcmd.o:	$(OBJDIR)/diffcmd_.c $(OBJDIR)/diffcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c $(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/doc_.c:	$(SRCDIR)/doc.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/doc.c >$@

$(OBJDIR)/doc.o:	$(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c

$(OBJDIR)/doc.h:	$(OBJDIR)/headers

$(OBJDIR)/encode_.c:	$(SRCDIR)/encode.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/encode.c >$@

$(OBJDIR)/encode.o:	$(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c

$(OBJDIR)/encode.h:	$(OBJDIR)/headers

$(OBJDIR)/event_.c:	$(SRCDIR)/event.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/event.c >$@

$(OBJDIR)/event.o:	$(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/event.o -c $(OBJDIR)/event_.c

$(OBJDIR)/event.h:	$(OBJDIR)/headers

$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/export.c >$@

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/file.c >$@

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

$(OBJDIR)/file.h:	$(OBJDIR)/headers

$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/finfo.c >$@

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.h:	$(OBJDIR)/headers

$(OBJDIR)/glob_.c:	$(SRCDIR)/glob.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/glob.c >$@

$(OBJDIR)/glob.o:	$(OBJDIR)/glob_.c $(OBJDIR)/glob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/glob.o -c $(OBJDIR)/glob_.c

$(OBJDIR)/glob.h:	$(OBJDIR)/headers

$(OBJDIR)/graph_.c:	$(SRCDIR)/graph.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/graph.c >$@

$(OBJDIR)/graph.o:	$(OBJDIR)/graph_.c $(OBJDIR)/graph.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c $(OBJDIR)/graph_.c

$(OBJDIR)/graph.h:	$(OBJDIR)/headers

$(OBJDIR)/gzip_.c:	$(SRCDIR)/gzip.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/gzip.c >$@

$(OBJDIR)/gzip.o:	$(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.h:	$(OBJDIR)/headers

$(OBJDIR)/http_.c:	$(SRCDIR)/http.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http.c >$@

$(OBJDIR)/http.o:	$(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c

$(OBJDIR)/http.h:	$(OBJDIR)/headers

$(OBJDIR)/http_socket_.c:	$(SRCDIR)/http_socket.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http_socket.c >$@

$(OBJDIR)/http_socket.o:	$(OBJDIR)/http_socket_.c $(OBJDIR)/http_socket.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c $(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.h:	$(OBJDIR)/headers

$(OBJDIR)/http_ssl_.c:	$(SRCDIR)/http_ssl.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http_ssl.c >$@

$(OBJDIR)/http_ssl.o:	$(OBJDIR)/http_ssl_.c $(OBJDIR)/http_ssl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_ssl.o -c $(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.h:	$(OBJDIR)/headers

$(OBJDIR)/http_transport_.c:	$(SRCDIR)/http_transport.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/http_transport.c >$@

$(OBJDIR)/http_transport.o:	$(OBJDIR)/http_transport_.c $(OBJDIR)/http_transport.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c $(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.h:	$(OBJDIR)/headers

$(OBJDIR)/import_.c:	$(SRCDIR)/import.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/import.c >$@

$(OBJDIR)/import.o:	$(OBJDIR)/import_.c $(OBJDIR)/import.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/import.o -c $(OBJDIR)/import_.c

$(OBJDIR)/import.h:	$(OBJDIR)/headers

$(OBJDIR)/info_.c:	$(SRCDIR)/info.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/info.c >$@

$(OBJDIR)/info.o:	$(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c

$(OBJDIR)/info.h:	$(OBJDIR)/headers

$(OBJDIR)/json_.c:	$(SRCDIR)/json.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json.c >$@

$(OBJDIR)/json.o:	$(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c

$(OBJDIR)/json.h:	$(OBJDIR)/headers

$(OBJDIR)/json_artifact_.c:	$(SRCDIR)/json_artifact.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_artifact.c >$@

$(OBJDIR)/json_artifact.o:	$(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.h:	$(OBJDIR)/headers

$(OBJDIR)/json_branch_.c:	$(SRCDIR)/json_branch.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_branch.c >$@

$(OBJDIR)/json_branch.o:	$(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.h:	$(OBJDIR)/headers

$(OBJDIR)/json_config_.c:	$(SRCDIR)/json_config.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_config.c >$@

$(OBJDIR)/json_config.o:	$(OBJDIR)/json_config_.c $(OBJDIR)/json_config.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_config.o -c $(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.h:	$(OBJDIR)/headers

$(OBJDIR)/json_diff_.c:	$(SRCDIR)/json_diff.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_diff.c >$@

$(OBJDIR)/json_diff.o:	$(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.h:	$(OBJDIR)/headers

$(OBJDIR)/json_dir_.c:	$(SRCDIR)/json_dir.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_dir.c >$@

$(OBJDIR)/json_dir.o:	$(OBJDIR)/json_dir_.c $(OBJDIR)/json_dir.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_dir.o -c $(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.h:	$(OBJDIR)/headers

$(OBJDIR)/json_finfo_.c:	$(SRCDIR)/json_finfo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_finfo.c >$@

$(OBJDIR)/json_finfo.o:	$(OBJDIR)/json_finfo_.c $(OBJDIR)/json_finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_finfo.o -c $(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/json_login_.c:	$(SRCDIR)/json_login.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_login.c >$@

$(OBJDIR)/json_login.o:	$(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.h:	$(OBJDIR)/headers

$(OBJDIR)/json_query_.c:	$(SRCDIR)/json_query.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_query.c >$@

$(OBJDIR)/json_query.o:	$(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.h:	$(OBJDIR)/headers

$(OBJDIR)/json_report_.c:	$(SRCDIR)/json_report.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_report.c >$@

$(OBJDIR)/json_report.o:	$(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.h:	$(OBJDIR)/headers

$(OBJDIR)/json_status_.c:	$(SRCDIR)/json_status.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_status.c >$@

$(OBJDIR)/json_status.o:	$(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.h:	$(OBJDIR)/headers

$(OBJDIR)/json_tag_.c:	$(SRCDIR)/json_tag.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_tag.c >$@

$(OBJDIR)/json_tag.o:	$(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.h:	$(OBJDIR)/headers

$(OBJDIR)/json_timeline_.c:	$(SRCDIR)/json_timeline.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_timeline.c >$@

$(OBJDIR)/json_timeline.o:	$(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/json_user_.c:	$(SRCDIR)/json_user.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_user.c >$@

$(OBJDIR)/json_user.o:	$(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.h:	$(OBJDIR)/headers

$(OBJDIR)/json_wiki_.c:	$(SRCDIR)/json_wiki.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/json_wiki.c >$@

$(OBJDIR)/json_wiki.o:	$(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/leaf_.c:	$(SRCDIR)/leaf.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/leaf.c >$@

$(OBJDIR)/leaf.o:	$(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.h:	$(OBJDIR)/headers

$(OBJDIR)/loadctrl_.c:	$(SRCDIR)/loadctrl.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/loadctrl.c >$@

$(OBJDIR)/loadctrl.o:	$(OBJDIR)/loadctrl_.c $(OBJDIR)/loadctrl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/loadctrl.o -c $(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.h:	$(OBJDIR)/headers

$(OBJDIR)/login_.c:	$(SRCDIR)/login.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/login.c >$@

$(OBJDIR)/login.o:	$(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c

$(OBJDIR)/login.h:	$(OBJDIR)/headers

$(OBJDIR)/lookslike_.c:	$(SRCDIR)/lookslike.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/lookslike.c >$@

$(OBJDIR)/lookslike.o:	$(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.h:	$(OBJDIR)/headers

$(OBJDIR)/main_.c:	$(SRCDIR)/main.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/main.c >$@

$(OBJDIR)/main.o:	$(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c

$(OBJDIR)/main.h:	$(OBJDIR)/headers

$(OBJDIR)/manifest_.c:	$(SRCDIR)/manifest.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/manifest.c >$@

$(OBJDIR)/manifest.o:	$(OBJDIR)/manifest_.c $(OBJDIR)/manifest.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c $(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_.c:	$(SRCDIR)/markdown.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/markdown.c >$@

$(OBJDIR)/markdown.o:	$(OBJDIR)/markdown_.c $(OBJDIR)/markdown.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown.o -c $(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_html_.c:	$(SRCDIR)/markdown_html.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/markdown_html.c >$@

$(OBJDIR)/markdown_html.o:	$(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.h:	$(OBJDIR)/headers

$(OBJDIR)/md5_.c:	$(SRCDIR)/md5.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/md5.c >$@

$(OBJDIR)/md5.o:	$(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c

$(OBJDIR)/md5.h:	$(OBJDIR)/headers

$(OBJDIR)/merge_.c:	$(SRCDIR)/merge.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/merge.c >$@

$(OBJDIR)/merge.o:	$(OBJDIR)/merge_.c $(OBJDIR)/merge.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c $(OBJDIR)/merge_.c

$(OBJDIR)/merge.h:	$(OBJDIR)/headers

$(OBJDIR)/merge3_.c:	$(SRCDIR)/merge3.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/merge3.c >$@

$(OBJDIR)/merge3.o:	$(OBJDIR)/merge3_.c $(OBJDIR)/merge3.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c $(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.h:	$(OBJDIR)/headers

$(OBJDIR)/moderate_.c:	$(SRCDIR)/moderate.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/moderate.c >$@

$(OBJDIR)/moderate.o:	$(OBJDIR)/moderate_.c $(OBJDIR)/moderate.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/moderate.o -c $(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.h:	$(OBJDIR)/headers

$(OBJDIR)/name_.c:	$(SRCDIR)/name.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/name.c >$@

$(OBJDIR)/name.o:	$(OBJDIR)/name_.c $(OBJDIR)/name.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c $(OBJDIR)/name_.c

$(OBJDIR)/name.h:	$(OBJDIR)/headers

$(OBJDIR)/path_.c:	$(SRCDIR)/path.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/path.c >$@

$(OBJDIR)/path.o:	$(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c

$(OBJDIR)/path.h:	$(OBJDIR)/headers

$(OBJDIR)/pivot_.c:	$(SRCDIR)/pivot.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/pivot.c >$@

$(OBJDIR)/pivot.o:	$(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.h:	$(OBJDIR)/headers

$(OBJDIR)/popen_.c:	$(SRCDIR)/popen.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/popen.c >$@

$(OBJDIR)/popen.o:	$(OBJDIR)/popen_.c $(OBJDIR)/popen.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/popen.o -c $(OBJDIR)/popen_.c

$(OBJDIR)/popen.h:	$(OBJDIR)/headers

$(OBJDIR)/pqueue_.c:	$(SRCDIR)/pqueue.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/pqueue.c >$@

$(OBJDIR)/pqueue.o:	$(OBJDIR)/pqueue_.c $(OBJDIR)/pqueue.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c $(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.h:	$(OBJDIR)/headers

$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/printf.c >$@

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/rebuild.c >$@

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.h:	$(OBJDIR)/headers

$(OBJDIR)/regexp_.c:	$(SRCDIR)/regexp.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/regexp.c >$@

$(OBJDIR)/regexp.o:	$(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.h:	$(OBJDIR)/headers

$(OBJDIR)/report_.c:	$(SRCDIR)/report.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/report.c >$@

$(OBJDIR)/report.o:	$(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c

$(OBJDIR)/report.h:	$(OBJDIR)/headers

$(OBJDIR)/rss_.c:	$(SRCDIR)/rss.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/rss.c >$@

$(OBJDIR)/rss.o:	$(OBJDIR)/rss_.c $(OBJDIR)/rss.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c $(OBJDIR)/rss_.c

$(OBJDIR)/rss.h:	$(OBJDIR)/headers

$(OBJDIR)/schema_.c:	$(SRCDIR)/schema.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/schema.c >$@

$(OBJDIR)/schema.o:	$(OBJDIR)/schema_.c $(OBJDIR)/schema.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c $(OBJDIR)/schema_.c

$(OBJDIR)/schema.h:	$(OBJDIR)/headers

$(OBJDIR)/search_.c:	$(SRCDIR)/search.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/search.c >$@

$(OBJDIR)/search.o:	$(OBJDIR)/search_.c $(OBJDIR)/search.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c $(OBJDIR)/search_.c

$(OBJDIR)/search.h:	$(OBJDIR)/headers

$(OBJDIR)/setup_.c:	$(SRCDIR)/setup.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/setup.c >$@

$(OBJDIR)/setup.o:	$(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c

$(OBJDIR)/setup.h:	$(OBJDIR)/headers

$(OBJDIR)/sha1_.c:	$(SRCDIR)/sha1.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/sha1.c >$@

$(OBJDIR)/sha1.o:	$(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.h:	$(OBJDIR)/headers

$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

$(OBJDIR)/skins.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlcmd_.c:	$(SRCDIR)/sqlcmd.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/sqlcmd.c >$@

$(OBJDIR)/sqlcmd.o:	$(OBJDIR)/sqlcmd_.c $(OBJDIR)/sqlcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sqlcmd.o -c $(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/stash_.c:	$(SRCDIR)/stash.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/stash.c >$@

$(OBJDIR)/stash.o:	$(OBJDIR)/stash_.c $(OBJDIR)/stash.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stash.o -c $(OBJDIR)/stash_.c

$(OBJDIR)/stash.h:	$(OBJDIR)/headers

$(OBJDIR)/stat_.c:	$(SRCDIR)/stat.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/stat.c >$@

$(OBJDIR)/stat.o:	$(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c

$(OBJDIR)/stat.h:	$(OBJDIR)/headers

$(OBJDIR)/style_.c:	$(SRCDIR)/style.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/style.c >$@

$(OBJDIR)/style.o:	$(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c $(OBJDIR)/style_.c

$(OBJDIR)/style.h:	$(OBJDIR)/headers

$(OBJDIR)/sync_.c:	$(SRCDIR)/sync.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/sync.c >$@

$(OBJDIR)/sync.o:	$(OBJDIR)/sync_.c $(OBJDIR)/sync.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c $(OBJDIR)/sync_.c

$(OBJDIR)/sync.h:	$(OBJDIR)/headers

$(OBJDIR)/tag_.c:	$(SRCDIR)/tag.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tag.c >$@

$(OBJDIR)/tag.o:	$(OBJDIR)/tag_.c $(OBJDIR)/tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c $(OBJDIR)/tag_.c

$(OBJDIR)/tag.h:	$(OBJDIR)/headers

$(OBJDIR)/tar_.c:	$(SRCDIR)/tar.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tar.c >$@

$(OBJDIR)/tar.o:	$(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c

$(OBJDIR)/tar.h:	$(OBJDIR)/headers

$(OBJDIR)/th_main_.c:	$(SRCDIR)/th_main.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/th_main.c >$@

$(OBJDIR)/th_main.o:	$(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.h:	$(OBJDIR)/headers

$(OBJDIR)/timeline_.c:	$(SRCDIR)/timeline.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/timeline.c >$@

$(OBJDIR)/timeline.o:	$(OBJDIR)/timeline_.c $(OBJDIR)/timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c $(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/tkt_.c:	$(SRCDIR)/tkt.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tkt.c >$@

$(OBJDIR)/tkt.o:	$(OBJDIR)/tkt_.c $(OBJDIR)/tkt.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c $(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.h:	$(OBJDIR)/headers

$(OBJDIR)/tktsetup_.c:	$(SRCDIR)/tktsetup.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/tktsetup.c >$@

$(OBJDIR)/tktsetup.o:	$(OBJDIR)/tktsetup_.c $(OBJDIR)/tktsetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c $(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.h:	$(OBJDIR)/headers

$(OBJDIR)/undo_.c:	$(SRCDIR)/undo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/undo.c >$@

$(OBJDIR)/undo.o:	$(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c

$(OBJDIR)/undo.h:	$(OBJDIR)/headers

$(OBJDIR)/unicode_.c:	$(SRCDIR)/unicode.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/unicode.c >$@

$(OBJDIR)/unicode.o:	$(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.h:	$(OBJDIR)/headers

$(OBJDIR)/update_.c:	$(SRCDIR)/update.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/update.c >$@

$(OBJDIR)/update.o:	$(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c

$(OBJDIR)/update.h:	$(OBJDIR)/headers

$(OBJDIR)/url_.c:	$(SRCDIR)/url.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/url.c >$@

$(OBJDIR)/url.o:	$(OBJDIR)/url_.c $(OBJDIR)/url.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c $(OBJDIR)/url_.c

$(OBJDIR)/url.h:	$(OBJDIR)/headers

$(OBJDIR)/user_.c:	$(SRCDIR)/user.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/user.c >$@

$(OBJDIR)/user.o:	$(OBJDIR)/user_.c $(OBJDIR)/user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c $(OBJDIR)/user_.c

$(OBJDIR)/user.h:	$(OBJDIR)/headers

$(OBJDIR)/utf8_.c:	$(SRCDIR)/utf8.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/utf8.c >$@

$(OBJDIR)/utf8.o:	$(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.h:	$(OBJDIR)/headers

$(OBJDIR)/util_.c:	$(SRCDIR)/util.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/util.c >$@

$(OBJDIR)/util.o:	$(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c

$(OBJDIR)/util.h:	$(OBJDIR)/headers

$(OBJDIR)/verify_.c:	$(SRCDIR)/verify.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/verify.c >$@

$(OBJDIR)/verify.o:	$(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c $(OBJDIR)/verify_.c

$(OBJDIR)/verify.h:	$(OBJDIR)/headers

$(OBJDIR)/vfile_.c:	$(SRCDIR)/vfile.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/vfile.c >$@

$(OBJDIR)/vfile.o:	$(OBJDIR)/vfile_.c $(OBJDIR)/vfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c $(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.h:	$(OBJDIR)/headers

$(OBJDIR)/wiki_.c:	$(SRCDIR)/wiki.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/wiki.c >$@

$(OBJDIR)/wiki.o:	$(OBJDIR)/wiki_.c $(OBJDIR)/wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c $(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/wikiformat_.c:	$(SRCDIR)/wikiformat.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/wikiformat.c >$@

$(OBJDIR)/wikiformat.o:	$(OBJDIR)/wikiformat_.c $(OBJDIR)/wikiformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c $(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.h:	$(OBJDIR)/headers

$(OBJDIR)/winfile_.c:	$(SRCDIR)/winfile.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/winfile.c >$@

$(OBJDIR)/winfile.o:	$(OBJDIR)/winfile_.c $(OBJDIR)/winfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winfile.o -c $(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.h:	$(OBJDIR)/headers

$(OBJDIR)/winhttp_.c:	$(SRCDIR)/winhttp.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/winhttp.c >$@

$(OBJDIR)/winhttp.o:	$(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.h:	$(OBJDIR)/headers

$(OBJDIR)/wysiwyg_.c:	$(SRCDIR)/wysiwyg.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/wysiwyg.c >$@

$(OBJDIR)/wysiwyg.o:	$(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.h:	$(OBJDIR)/headers

$(OBJDIR)/xfer_.c:	$(SRCDIR)/xfer.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/xfer.c >$@

$(OBJDIR)/xfer.o:	$(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.h:	$(OBJDIR)/headers

$(OBJDIR)/xfersetup_.c:	$(SRCDIR)/xfersetup.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/xfersetup.c >$@

$(OBJDIR)/xfersetup.o:	$(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.h:	$(OBJDIR)/headers

$(OBJDIR)/zip_.c:	$(SRCDIR)/zip.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/zip.c >$@

$(OBJDIR)/zip.o:	$(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $@

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
	$(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $@

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $@

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $@

$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -c $(SRCDIR)/th_tcl.c -o $@


$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $@

$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $@

#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#

.PHONY: all install test clean

Changes to src/makemake.tcl.
10
11
12
13
14
15
16
17
18



19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
# Run this script while in the "src" subdirectory.  Like this:
#
#      tclsh makemake.tcl
#
#############################################################################

# Basenames of all source files that get preprocessed using
# "translate" and "makeheaders".  To add new source files to the
# project, simply add the basename to this list and rerun this script.



#
set src {
  add
  allrepo
  attach
  bag
  bisect
  blob
  branch
  browse

  cache
  captcha
  cgi
  checkin
  checkout
  clearsign
  clone







|

>
>
>










>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Run this script while in the "src" subdirectory.  Like this:
#
#      tclsh makemake.tcl
#
#############################################################################

# Basenames of all source files that get preprocessed using
# "translate" and "makeheaders".  To add new C-language source files to the
# project, simply add the basename to this list and rerun this script.
#
# Set the separate extra_files variable further down for how to add non-C
# files, such as string and BLOB resources.
#
set src {
  add
  allrepo
  attach
  bag
  bisect
  blob
  branch
  browse
  builtin
  cache
  captcha
  cgi
  checkin
  checkout
  clearsign
  clone
126
127
128
129
130
131
132






133
134
135
136
137
138
139
  winhttp
  wysiwyg
  xfer
  xfersetup
  zip
  http_ssl
}







# Options used to compile the included SQLite library.
#
set SQLITE_OPTIONS {
  -DNDEBUG=1
  -DSQLITE_OMIT_LOAD_EXTENSION=1
  -DSQLITE_ENABLE_LOCKING_STYLE=0







>
>
>
>
>
>







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  winhttp
  wysiwyg
  xfer
  xfersetup
  zip
  http_ssl
}

# Additional resource files that get built into the executable.
#
set extra_files {
  diff.tcl
}

# Options used to compile the included SQLite library.
#
set SQLITE_OPTIONS {
  -DNDEBUG=1
  -DSQLITE_OMIT_LOAD_EXTENSION=1
  -DSQLITE_ENABLE_LOCKING_STYLE=0
208
209
210
211
212
213
214
215
216
217
218
219
220
221





222
223
224
225
226
227
228
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
# This file is included by primary Makefile.
#

XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR) -I$(OBJDIR)

}
writeln -nonewline "SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(SRCDIR)/$s.c"
}





writeln "\n"
writeln -nonewline "TRANS_SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(OBJDIR)/${s}_.c"
}
writeln "\n"
writeln -nonewline "OBJ ="







|






>
>
>
>
>







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
# This file is included by primary Makefile.
#

XTCC = $(TCC) -I. -I$(SRCDIR) -I$(OBJDIR) $(TCCFLAGS) $(CFLAGS)

}
writeln -nonewline "SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(SRCDIR)/$s.c"
}
writeln "\n"
writeln -nonewline "EXTRA_FILES ="
foreach s [lsort $extra_files] {
  writeln -nonewline " \\\n  \$(SRCDIR)/$s"
}
writeln "\n"
writeln -nonewline "TRANS_SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(OBJDIR)/${s}_.c"
}
writeln "\n"
writeln -nonewline "OBJ ="
239
240
241
242
243
244
245



246
247
248
249
250
251
252
253
254
255
256
257



258
259
260



261
262
263
264
265
266
267
    <<<MINIZ_OPTIONS>>> [join $MINIZ_OPTIONS " \\\n                "]] {
all:	$(OBJDIR) $(APPNAME)

install:	$(APPNAME)
	mkdir -p $(INSTALLDIR)
	mv $(APPNAME) $(INSTALLDIR)




$(OBJDIR):
	-mkdir $(OBJDIR)

$(OBJDIR)/translate:	$(SRCDIR)/translate.c
	$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c

$(OBJDIR)/makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c

$(OBJDIR)/mkindex:	$(SRCDIR)/mkindex.c
	$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c




$(OBJDIR)/mkversion:	$(SRCDIR)/mkversion.c
	$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c




# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion







>
>
>












>
>
>



>
>
>







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
    <<<MINIZ_OPTIONS>>> [join $MINIZ_OPTIONS " \\\n                "]] {
all:	$(OBJDIR) $(APPNAME)

install:	$(APPNAME)
	mkdir -p $(INSTALLDIR)
	mv $(APPNAME) $(INSTALLDIR)

codecheck:	$(TRANS_SRC) $(OBJDIR)/codecheck1
	$(OBJDIR)/codecheck1 $(TRANS_SRC)

$(OBJDIR):
	-mkdir $(OBJDIR)

$(OBJDIR)/translate:	$(SRCDIR)/translate.c
	$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c

$(OBJDIR)/makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c

$(OBJDIR)/mkindex:	$(SRCDIR)/mkindex.c
	$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c

$(OBJDIR)/mkbuiltin:	$(SRCDIR)/mkbuiltin.c
	$(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c

$(OBJDIR)/mkversion:	$(SRCDIR)/mkversion.c
	$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c

$(OBJDIR)/codecheck1:	$(SRCDIR)/codecheck1.c
	$(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c

# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
 $(OBJDIR)/th.o <<<NEXT_LINE>>>
 $(OBJDIR)/th_lang.o <<<NEXT_LINE>>>
 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
 $(OBJDIR)/cson_amalgamation.o
}]

writeln {
$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)

	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(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:
	# noop







|
>







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
 $(OBJDIR)/th.o <<<NEXT_LINE>>>
 $(OBJDIR)/th_lang.o <<<NEXT_LINE>>>
 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
 $(OBJDIR)/cson_amalgamation.o
}]

writeln {
$(APPNAME):	$(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
	$(OBJDIR)/codecheck1 $(TRANS_SRC)
	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(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:
	# noop
327
328
329
330
331
332
333
334




335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
}
append mhargs "\$(SRCDIR)/sqlite3.h <<<NEXT_LINE>>>"
append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>"
#append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>"
append mhargs "\$(OBJDIR)/VERSION.h"
set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs]
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex"
writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@"




writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
writeln "\t\$(OBJDIR)/makeheaders $mhargs"
writeln "\ttouch \$(OBJDIR)/headers"
writeln "\$(OBJDIR)/headers: Makefile"
writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h"
writeln "Makefile:"
set extra_h(main) " \$(OBJDIR)/page_index.h "


foreach s [lsort $src] {
  writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate"
  writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
  writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
  writeln "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c \$(OBJDIR)/${s}_.c\n"
  writeln "\$(OBJDIR)/$s.h:\t\$(OBJDIR)/headers"
}

writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"

writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"

writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"

writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"

writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n"

writeln {
$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $(OBJDIR)/miniz.o

$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o

#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#

.PHONY: all install test clean







|
>
>
>
>
|






>



|


|



|


|


|


|


|



|


|







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
}
append mhargs "\$(SRCDIR)/sqlite3.h <<<NEXT_LINE>>>"
append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>"
#append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>"
append mhargs "\$(OBJDIR)/VERSION.h"
set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs]
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex"
writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >\$@\n"

writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)"
writeln "\t\$(OBJDIR)/mkbuiltin \$(EXTRA_FILES) >\$@\n"

writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
writeln "\t\$(OBJDIR)/makeheaders $mhargs"
writeln "\ttouch \$(OBJDIR)/headers"
writeln "\$(OBJDIR)/headers: Makefile"
writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h"
writeln "Makefile:"
set extra_h(main) " \$(OBJDIR)/page_index.h "
set extra_h(builtin) " \$(OBJDIR)/builtin_data.h "

foreach s [lsort $src] {
  writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate"
  writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$@\n"
  writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
  writeln "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c \$(OBJDIR)/${s}_.c\n"
  writeln "\$(OBJDIR)/$s.h:\t\$(OBJDIR)/headers\n"
}

writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) -c \$(SRCDIR)/sqlite3.c -o \$@\n"

writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -c \$(SRCDIR)/shell.c -o \$@\n"

writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"

writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$@\n"

writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"

writeln {
$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $@

$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $@

#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#

.PHONY: all install test clean
489
490
491
492
493
494
495




















496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib





















#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
#    Fossil source code directory and the target OpenSSL source directory.
#
OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i

#### Either the directory where the Tcl library is installed or the Tcl
#    source code directory resides (depending on the value of the macro
#    FOSSIL_TCL_SOURCE).  If this points to the Tcl install directory,
#    this directory must have "include" and "lib" sub-directories.  If
#    this points to the Tcl source code directory, this directory must
#    have "generic" and "win" sub-directories.  The recommended usage







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|







519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib

ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif

ifndef X64
SSLCONFIG = mingw
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else
SSLCONFIG = mingw64
ZLIBCONFIG = 
LIBTARGETS =
endif

ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
#    Fossil source code directory and the target OpenSSL source directory.
#
OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j

#### Either the directory where the Tcl library is installed or the Tcl
#    source code directory resides (depending on the value of the macro
#    FOSSIL_TCL_SOURCE).  If this points to the Tcl install directory,
#    this directory must have "include" and "lib" sub-directories.  If
#    this points to the Tcl source code directory, this directory must
#    have "generic" and "win" sub-directories.  The recommended usage
716
717
718
719
720
721
722





723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749


750
751
752
753
754
755
756
757
758
759
760
761


762
763
764
765
766
767
768
#--------------------------------------------------------
XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR)
}
writeln -nonewline "SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(SRCDIR)/$s.c"
}





writeln "\n"
writeln -nonewline "TRANS_SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(OBJDIR)/${s}_.c"
}
writeln "\n"
writeln -nonewline "OBJ ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n \$(OBJDIR)/$s.o"
}
writeln "\n"
writeln "APPNAME    = ${name}.exe"
writeln "APPTARGETS ="
writeln "LIBTARGETS ="
writeln {
#### If the USE_WINDOWS variable exists, it is assumed that we are building
#    inside of a Windows-style shell; otherwise, it is assumed that we are
#    building inside of a Unix-style shell.  Note that the "move" command is
#    broken when attempting to use it from the Windows shell via MinGW make
#    because the SHELL variable is only used for certain commands that are
#    recognized internally by make.
#
ifdef USE_WINDOWS
TRANSLATE   = $(subst /,\,$(OBJDIR)/translate.exe)
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
MKINDEX     = $(subst /,\,$(OBJDIR)/mkindex.exe)
VERSION     = $(subst /,\,$(OBJDIR)/version.exe)


CAT         = type
CP          = copy
GREP        = find
MV          = copy
RM          = del /Q
MKDIR       = -mkdir
RMDIR       = rmdir /S /Q
else
TRANSLATE   = $(OBJDIR)/translate.exe
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
MKINDEX     = $(OBJDIR)/mkindex.exe
VERSION     = $(OBJDIR)/version.exe


CAT         = cat
CP          = cp
GREP        = grep
MV          = mv
RM          = rm -f
MKDIR       = -mkdir -p
RMDIR       = rm -rf







>
>
>
>
>













<












|
>
>











|
>
>







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
#--------------------------------------------------------
XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR)
}
writeln -nonewline "SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(SRCDIR)/$s.c"
}
writeln "\n"
writeln -nonewline "EXTRA_FILES ="
foreach s [lsort $extra_files] {
  writeln -nonewline " \\\n  \$(SRCDIR)/$s"
}
writeln "\n"
writeln -nonewline "TRANS_SRC ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n  \$(OBJDIR)/${s}_.c"
}
writeln "\n"
writeln -nonewline "OBJ ="
foreach s [lsort $src] {
  writeln -nonewline " \\\n \$(OBJDIR)/$s.o"
}
writeln "\n"
writeln "APPNAME    = ${name}.exe"
writeln "APPTARGETS ="

writeln {
#### If the USE_WINDOWS variable exists, it is assumed that we are building
#    inside of a Windows-style shell; otherwise, it is assumed that we are
#    building inside of a Unix-style shell.  Note that the "move" command is
#    broken when attempting to use it from the Windows shell via MinGW make
#    because the SHELL variable is only used for certain commands that are
#    recognized internally by make.
#
ifdef USE_WINDOWS
TRANSLATE   = $(subst /,\,$(OBJDIR)/translate.exe)
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
MKINDEX     = $(subst /,\,$(OBJDIR)/mkindex.exe)
MKBUILTIN   = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
MKVERSION   = $(subst /,\,$(OBJDIR)/mkversion.exe)
CODECHECK1  = $(subst /,\,$(OBJDIR)/codecheck1.exe)
CAT         = type
CP          = copy
GREP        = find
MV          = copy
RM          = del /Q
MKDIR       = -mkdir
RMDIR       = rmdir /S /Q
else
TRANSLATE   = $(OBJDIR)/translate.exe
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
MKINDEX     = $(OBJDIR)/mkindex.exe
MKBUILTIN   = $(OBJDIR)/mkbuiltin.exe
MKVERSION   = $(OBJDIR)/mkversion.exe
CODECHECK1  = $(OBJDIR)/codecheck1.exe
CAT         = cat
CP          = cp
GREP        = grep
MV          = mv
RM          = rm -f
MKDIR       = -mkdir -p
RMDIR       = rm -rf
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812



813
814



815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
ifdef USE_WINDOWS
	$(MKDIR) $(subst /,\,$(OBJDIR))
else
	$(MKDIR) $(OBJDIR)
endif

$(TRANSLATE):	$(SRCDIR)/translate.c
	$(BCC) -o $(TRANSLATE) $(SRCDIR)/translate.c

$(MAKEHEADERS):	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c

$(MKINDEX):	$(SRCDIR)/mkindex.c
	$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c




$(VERSION): $(SRCDIR)/mkversion.c
	$(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c




# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
	$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h

# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
# to 1. If it is set to 1, then there is no need to build or link
# the sqlite3.o object. Instead, the system SQLite will be linked
# using -lsqlite3.
SQLITE3_OBJ.1 =
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o







|


|


|

>
>
>
|
|
>
>
>







|
|







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
ifdef USE_WINDOWS
	$(MKDIR) $(subst /,\,$(OBJDIR))
else
	$(MKDIR) $(OBJDIR)
endif

$(TRANSLATE):	$(SRCDIR)/translate.c
	$(BCC) -o $@ $(SRCDIR)/translate.c

$(MAKEHEADERS):	$(SRCDIR)/makeheaders.c
	$(BCC) -o $@ $(SRCDIR)/makeheaders.c

$(MKINDEX):	$(SRCDIR)/mkindex.c
	$(BCC) -o $@ $(SRCDIR)/mkindex.c

$(MKBUILTIN):	$(SRCDIR)/mkbuiltin.c
	$(BCC) -o $@ $(SRCDIR)/mkbuiltin.c

$(MKVERSION): $(SRCDIR)/mkversion.c
	$(BCC) -o $@ $(SRCDIR)/mkversion.c

$(CODECHECK1):	$(SRCDIR)/codecheck1.c
	$(BCC) -o $@ $(SRCDIR)/codecheck1.c

# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
	$(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$@

# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
# to 1. If it is set to 1, then there is no need to build or link
# the sqlite3.o object. Instead, the system SQLite will be linked
# using -lsqlite3.
SQLITE3_OBJ.1 =
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o
847
848
849
850
851
852
853
854
855
856
857







858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887

888
889
890
891
892
893
894
895
 $(OBJDIR)/th_lang.o <<<NEXT_LINE>>>
 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
 $(OBJDIR)/cson_amalgamation.o
}]

writeln {
zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a

clean-zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean








ifndef FOSSIL_ENABLE_MINIZ
LIBTARGETS += zlib
endif

openssl:	$(LIBTARGETS)
ifndef FOSSIL_ENABLE_MINIZ
	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib mingw
else
	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) mingw
endif
	$(MAKE) -C $(OPENSSLLIBDIR) build_libs

clean-openssl:
	$(MAKE) -C $(OPENSSLLIBDIR) clean

tcl:
	cd $(TCLSRCDIR)/win;./configure
	$(MAKE) -C $(TCLSRCDIR)/win $(TCLTARGET)

clean-tcl:
	$(MAKE) -C $(TCLSRCDIR)/win distclean

APPTARGETS += $(LIBTARGETS)

ifdef FOSSIL_BUILD_SSL
APPTARGETS += openssl
endif

$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)

	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o

# 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:
	# noop








|



>
>
>
>
>
>
>






<
<
<
|
<


















|
>
|







911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934



935

936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
 $(OBJDIR)/th_lang.o <<<NEXT_LINE>>>
 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
 $(OBJDIR)/cson_amalgamation.o
}]

writeln {
zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) $(ZLIBCONFIG) -f win32/Makefile.gcc libz.a

clean-zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean

$(ZLIBDIR)/inffas86.o:
	$(TCC) -c -o $@ -DASMINF -I$(ZLIBDIR) -O3 $(ZLIBDIR)/contrib/inflate86/inffas86.c

$(ZLIBDIR)/match.o:
	$(TCC) -c -o $@ -DASMV $(ZLIBDIR)/contrib/asm686/match.S


ifndef FOSSIL_ENABLE_MINIZ
LIBTARGETS += zlib
endif

openssl:	$(LIBTARGETS)



	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)

	$(MAKE) -C $(OPENSSLLIBDIR) build_libs

clean-openssl:
	$(MAKE) -C $(OPENSSLLIBDIR) clean

tcl:
	cd $(TCLSRCDIR)/win;./configure
	$(MAKE) -C $(TCLSRCDIR)/win $(TCLTARGET)

clean-tcl:
	$(MAKE) -C $(TCLSRCDIR)/win distclean

APPTARGETS += $(LIBTARGETS)

ifdef FOSSIL_BUILD_SSL
APPTARGETS += openssl
endif

$(APPNAME):	$(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
	$(CODECHECK1) $(TRANS_SRC)
	$(TCC) -o $@ $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o

# 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:
	# noop

915
916
917
918
919
920
921
922




923
924
925
926
927
928

929
930
931
932
933
934
935
936
937
938
939
  append mhargs "\$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h"
  set extra_h($s) { }
}
append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h"
append mhargs " \\\n\t\t\$(SRCDIR)/th.h"
append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h"
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)"
writeln "\t\$(MKINDEX) \$(TRANS_SRC) >$@\n"




writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h"
writeln "\t\$(MAKEHEADERS) $mhargs"
writeln "\techo Done >\$(OBJDIR)/headers\n"
writeln "\$(OBJDIR)/headers: Makefile\n"
writeln "Makefile:\n"
set extra_h(main) " \$(OBJDIR)/page_index.h "


foreach s [lsort $src] {
  writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)"
  writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
  writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
  writeln "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c \$(OBJDIR)/${s}_.c\n"
  writeln "\$(OBJDIR)/${s}.h:\t\$(OBJDIR)/headers\n"
}

set SQLITE_WIN32_OPTIONS $SQLITE_OPTIONS
lappend SQLITE_WIN32_OPTIONS -DSQLITE_WIN32_NO_ANSI







|
>
>
>
>
|





>



|







983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
  append mhargs "\$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h"
  set extra_h($s) { }
}
append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h"
append mhargs " \\\n\t\t\$(SRCDIR)/th.h"
append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h"
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)"
writeln "\t\$(MKINDEX) \$(TRANS_SRC) >\$@\n"

writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)"
writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >\$@\n"

writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h"
writeln "\t\$(MAKEHEADERS) $mhargs"
writeln "\techo Done >\$(OBJDIR)/headers\n"
writeln "\$(OBJDIR)/headers: Makefile\n"
writeln "Makefile:\n"
set extra_h(main) " \$(OBJDIR)/page_index.h "
set extra_h(builtin) " \$(OBJDIR)/builtin_data.h "

foreach s [lsort $src] {
  writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)"
  writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$@\n"
  writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
  writeln "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c \$(OBJDIR)/${s}_.c\n"
  writeln "\$(OBJDIR)/${s}.h:\t\$(OBJDIR)/headers\n"
}

set SQLITE_WIN32_OPTIONS $SQLITE_OPTIONS
lappend SQLITE_WIN32_OPTIONS -DSQLITE_WIN32_NO_ANSI
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
set j " \\\n                "
writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS $j]\n"
set j " \\\n                "
writeln "MINIZ_OPTIONS = [join $MINIZ_WIN32_OPTIONS $j]\n"

writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c \$(SRCDIR)/../win/Makefile.mingw"
writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"

writeln "\$(OBJDIR)/cson_amalgamation.o:\t\$(SRCDIR)/cson_amalgamation.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/cson_amalgamation.c -o \$(OBJDIR)/cson_amalgamation.o\n"
writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/jsos_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h\n"

writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h \$(SRCDIR)/../win/Makefile.mingw"
writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"

writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"

writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"

writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n"

writeln "\$(OBJDIR)/miniz.o:\t\$(SRCDIR)/miniz.c"
writeln "\t\$(XTCC) \$(MINIZ_OPTIONS) -c \$(SRCDIR)/miniz.c -o \$(OBJDIR)/miniz.o\n"

close $output_file
#
# End of the win/Makefile.mingw output
##############################################################################
##############################################################################
##############################################################################







|


|



|


|


|


|


|







1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
set j " \\\n                "
writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS $j]\n"
set j " \\\n                "
writeln "MINIZ_OPTIONS = [join $MINIZ_WIN32_OPTIONS $j]\n"

writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c \$(SRCDIR)/../win/Makefile.mingw"
writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) -c \$(SRCDIR)/sqlite3.c -o \$@\n"

writeln "\$(OBJDIR)/cson_amalgamation.o:\t\$(SRCDIR)/cson_amalgamation.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/cson_amalgamation.c -o \$@\n"
writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/jsos_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h\n"

writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h \$(SRCDIR)/../win/Makefile.mingw"
writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -c \$(SRCDIR)/shell.c -o \$@\n"

writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"

writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$@\n"

writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"

writeln "\$(OBJDIR)/miniz.o:\t\$(SRCDIR)/miniz.c"
writeln "\t\$(XTCC) \$(MINIZ_OPTIONS) -c \$(SRCDIR)/miniz.c -o \$@\n"

close $output_file
#
# End of the win/Makefile.mingw output
##############################################################################
##############################################################################
##############################################################################
1031
1032
1033
1034
1035
1036
1037
1038
1039

1040
1041
1042
1043
1044
1045
1046
RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

all: $(APPNAME)

$(APPNAME) : translate$E mkindex$E headers  $(OBJ) $(OBJDIR)\link
	cd $(OBJDIR)

	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res}
writeln -nonewline "\t+echo "







|

>







1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

all: $(APPNAME)

$(APPNAME) : translate$E mkindex$E codecheck1$E headers  $(OBJ) $(OBJDIR)\link
	cd $(OBJDIR)
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res}
writeln -nonewline "\t+echo "
1060
1061
1062
1063
1064
1065
1066



1067



1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089



1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) -o$@ $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) -o$@ $**




version$E: $B\src\mkversion.c



	$(BCC) -o$@ $**

$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
	$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**

$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
	$(TCC) -o$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $**

$(OBJDIR)\th$O : $(SRCDIR)\th.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
	cp $@ $@

VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
	+$** > $@

page_index.h: mkindex$E $(SRC)
	+$** > $@




clean:
	-del $(OBJDIR)\*.obj
	-del *.obj *_.c *.h *.map

realclean:
	-del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E

$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h







>
>
>
|
>
>
>

















|




>
>
>






|







1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) -o$@ $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) -o$@ $**

mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
	$(BCC) -o$@ $**

mkversion$E: $(SRCDIR)\mkversion.c
	$(BCC) -o$@ $**

codecheck1$E: $(SRCDIR)\codecheck1.c
	$(BCC) -o$@ $**

$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
	$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**

$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
	$(TCC) -o$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $**

$(OBJDIR)\th$O : $(SRCDIR)\th.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
	cp $@ $@

VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
	+$** > $@

page_index.h: mkindex$E $(SRC)
	+$** > $@

builtin_data.h:	mkbuiltin$E $(EXTRA_FILES)
	+$** > $@

clean:
	-del $(OBJDIR)\*.obj
	-del *.obj *_.c *.h *.map

realclean:
	-del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E

$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
foreach s [lsort $src] {
  writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h"
  writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n"
  writeln "${s}_.c : \$(SRCDIR)\\$s.c"
  writeln "\t+translate\$E \$** > \$@\n"
}

writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E "
foreach s [lsort $src] {
  writeln -nonewline "${s}_.c:$s.h "
}
writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
writeln "\t@copy /Y nul: headers"

close $output_file







|







1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
foreach s [lsort $src] {
  writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h"
  writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n"
  writeln "${s}_.c : \$(SRCDIR)\\$s.c"
  writeln "\t+translate\$E \$** > \$@\n"
}

writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
foreach s [lsort $src] {
  writeln -nonewline "${s}_.c:$s.h "
}
writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
writeln "\t@copy /Y nul: headers"

close $output_file
1139
1140
1141
1142
1143
1144
1145








1146
1147
1148
1149
1150
1151
1152
set output_file [open ../win/Makefile.msc w]
fconfigure $output_file -translation binary

writeln {#
##############################################################################
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
##############################################################################








#
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
B       = ..
SRCDIR  = $B\src







>
>
>
>
>
>
>
>







1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
set output_file [open ../win/Makefile.msc w]
fconfigure $output_file -translation binary

writeln {#
##############################################################################
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
##############################################################################
#
# This Makefile will only function correctly if used from a sub-directory
# that is a direct child of the top-level directory for this project.
#
!if !exist("..\.fossil-settings")
!error "Please change the current directory to the one containing this file."
!endif

#
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
B       = ..
SRCDIR  = $B\src
1160
1161
1162
1163
1164
1165
1166



1167
1168
1169
1170
1171
1172
1173
1174
1175



1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

1190
















1191
1192
1193
1194
1195
1196
1197
# be built from source code.  The PERLDIR variable should point to
# the directory containing the main Perl binary (i.e. "perl.exe").
PERLDIR = C:\Perl\bin
PERL    = perl.exe

# Uncomment to enable debug symbols
# DEBUG = 1




# Uncomment to enable JSON API
# FOSSIL_ENABLE_JSON = 1

# Uncomment to enable miniz usage
# FOSSIL_ENABLE_MINIZ = 1

# Uncomment to enable SSL support
# FOSSIL_ENABLE_SSL = 1




# Uncomment to enable TH1 scripts in embedded documentation files
# FOSSIL_ENABLE_TH1_DOCS = 1

# Uncomment to enable TH1 hooks
# FOSSIL_ENABLE_TH1_HOOKS = 1

# Uncomment to enable Tcl support
# FOSSIL_ENABLE_TCL = 1

!ifdef FOSSIL_ENABLE_SSL
SSLDIR    = $(B)\compat\openssl-1.0.1i
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32

SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
















!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
!endif







>
>
>









>
>
>











|


>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
# be built from source code.  The PERLDIR variable should point to
# the directory containing the main Perl binary (i.e. "perl.exe").
PERLDIR = C:\Perl\bin
PERL    = perl.exe

# Uncomment to enable debug symbols
# DEBUG = 1

# Uncomment to support Windows XP with Visual Studio 201x
# FOSSIL_ENABLE_WINXP = 1

# Uncomment to enable JSON API
# FOSSIL_ENABLE_JSON = 1

# Uncomment to enable miniz usage
# FOSSIL_ENABLE_MINIZ = 1

# Uncomment to enable SSL support
# FOSSIL_ENABLE_SSL = 1

# Uncomment to build SSL libraries
# FOSSIL_BUILD_SSL = 1

# Uncomment to enable TH1 scripts in embedded documentation files
# FOSSIL_ENABLE_TH1_DOCS = 1

# Uncomment to enable TH1 hooks
# FOSSIL_ENABLE_TH1_HOOKS = 1

# Uncomment to enable Tcl support
# FOSSIL_ENABLE_TCL = 1

!ifdef FOSSIL_ENABLE_SSL
SSLDIR    = $(B)\compat\openssl-1.0.1j
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32
SSLLFLAGS = /nologo /opt:ref /debug
SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
!message Using 'x64' platform for OpenSSL...
SSLCONFIG = VC-WIN64A no-asm
SSLSETUP  = ms\do_win64a.bat
SSLNMAKE  = ms\nt.mak all
!elseif "$(PLATFORM)"=="ia64"
!message Using 'ia64' platform for OpenSSL...
SSLCONFIG = VC-WIN64I no-asm
SSLSETUP  = ms\do_win64i.bat
SSLNMAKE  = ms\nt.mak all
!else
!message Assuming 'x86' platform for OpenSSL...
SSLCONFIG = VC-WIN32 no-asm
SSLSETUP  = ms\do_ms.bat
SSLNMAKE  = ms\nt.mak all
!endif
!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
!endif
1213
1214
1215
1216
1217
1218
1219











1220
1221
1222
1223
1224
1225
1226

!ifdef FOSSIL_ENABLE_TCL
INCL      = $(INCL) /I$(TCLINCDIR)
!endif

CFLAGS    = /nologo
LDFLAGS   = /NODEFAULTLIB:msvcrt /MANIFEST:NO












!ifdef DEBUG
CFLAGS    = $(CFLAGS) /Zi /MTd /Od
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) /MT /O2
!endif







>
>
>
>
>
>
>
>
>
>
>







1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351

!ifdef FOSSIL_ENABLE_TCL
INCL      = $(INCL) /I$(TCLINCDIR)
!endif

CFLAGS    = /nologo
LDFLAGS   = /NODEFAULTLIB:msvcrt /MANIFEST:NO

!ifdef FOSSIL_ENABLE_WINXP
XPCFLAGS  = $(XPCFLAGS) /D_USING_V110_SDK71_=1
CFLAGS    = $(CFLAGS) $(XPCFLAGS)
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
!else
XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
!endif
LDFLAGS   = $(LDFLAGS) $(XPLDFLAGS)
!endif

!ifdef DEBUG
CFLAGS    = $(CFLAGS) /Zi /MTd /Od
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) /MT /O2
!endif
1291
1292
1293
1294
1295
1296
1297










1298
1299
1300
1301
1302
1303
1304
foreach s [lsort $src] {
  if {$i > 0} {
    writeln " \\"
    writeln -nonewline "        "
  }
  writeln -nonewline "${s}_.c"; incr i
}










writeln "\n"
set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation]
writeln -nonewline "OBJ   = "
set i 0
foreach s [lsort [concat $src $AdditionalObj]] {
  if {$i > 0} {
    writeln " \\"







>
>
>
>
>
>
>
>
>
>







1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
foreach s [lsort $src] {
  if {$i > 0} {
    writeln " \\"
    writeln -nonewline "        "
  }
  writeln -nonewline "${s}_.c"; incr i
}
writeln "\n"
writeln -nonewline "EXTRA_FILES   = "
set i 0
foreach s [lsort $extra_files] {
  if {$i > 0} {
    writeln " \\"
    writeln -nonewline "        "
  }
  writeln -nonewline "\$(SRCDIR)\\${s}"; incr i
}
writeln "\n"
set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation]
writeln -nonewline "OBJ   = "
set i 0
foreach s [lsort [concat $src $AdditionalObj]] {
  if {$i > 0} {
    writeln " \\"
1319
1320
1321
1322
1323
1324
1325



1326

1327
1328
1329
1330
1331
1332
1333
1334
1335



1336

1337
1338
1339
1340
1341
1342
1343

1344
1345

1346
1347
1348

1349
1350
1351
1352
1353
1354
1355
PDBNAME    = $(OX)\fossil$(P)
APPTARGETS =

all: $(OX) $(APPNAME)

zlib:
	@echo Building zlib from "$(ZLIBDIR)"...



	@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd


!ifdef FOSSIL_ENABLE_SSL
openssl:
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure VC-WIN32 no-asm && popd
	@pushd "$(SSLDIR)" && call ms\do_ms.bat && popd



	@pushd "$(SSLDIR)" && $(MAKE) /f ms\nt.mak all && popd

!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif

!ifdef FOSSIL_ENABLE_SSL

APPTARGETS = $(APPTARGETS) openssl
!endif


$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
	cd $(OX)

	link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts

$(OX)\linkopts: $B\win\Makefile.msc}
set redir {>}
foreach s [lsort [concat $src $AdditionalObj]] {
  writeln "\techo \$(OX)\\$s.obj $redir \$@"
  set redir {>>}







>
>
>

>







|
|
>
>
>
|
>







>


>

|

>







1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
PDBNAME    = $(OX)\fossil$(P)
APPTARGETS =

all: $(OX) $(APPNAME)

zlib:
	@echo Building zlib from "$(ZLIBDIR)"...
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
!else
	@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
!endif

!ifdef FOSSIL_ENABLE_SSL
openssl:
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
	@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
!else
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
!endif
!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif

!ifdef FOSSIL_ENABLE_SSL
!ifdef FOSSIL_BUILD_SSL
APPTARGETS = $(APPTARGETS) openssl
!endif
!endif

$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
	cd $(OX)
	codecheck1$E $(SRC)
	link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts

$(OX)\linkopts: $B\win\Makefile.msc}
set redir {>}
foreach s [lsort [concat $src $AdditionalObj]] {
  writeln "\techo \$(OX)\\$s.obj $redir \$@"
  set redir {>>}
1368
1369
1370
1371
1372
1373
1374



1375



1376
1377
1378
1379
1380
1381
1382

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) $**




mkversion$E: $B\src\mkversion.c



	$(BCC) $**

$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
	$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c

$(OX)\sqlite3$O : $(SRCDIR)\sqlite3.c $B\win\Makefile.msc
	$(TCC) /Fo$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SRCDIR)\sqlite3.c







>
>
>
|
>
>
>







1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) $**

mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
	$(BCC) $**

mkversion$E: $(SRCDIR)\mkversion.c
	$(BCC) $**

codecheck1$E: $(SRCDIR)\codecheck1.c
	$(BCC) $**

$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
	$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c

$(OX)\sqlite3$O : $(SRCDIR)\sqlite3.c $B\win\Makefile.msc
	$(TCC) /Fo$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SRCDIR)\sqlite3.c
1397
1398
1399
1400
1401
1402
1403



1404
1405
1406
1407
1408
1409
1410
	$** > $@
$(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c
	$(TCC) /Fo$@ /c $**

page_index.h: mkindex$E $(SRC)
	$** > $@




clean:
	-del $(OX)\*.obj
	-del *.obj
	-del *_.c
	-del *.h
	-del *.ilk
	-del *.map







>
>
>







1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
	$** > $@
$(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c
	$(TCC) /Fo$@ /c $**

page_index.h: mkindex$E $(SRC)
	$** > $@

builtin_data.h:	mkbuiltin$E $(EXTRA_FILES)
	$** > $@

clean:
	-del $(OX)\*.obj
	-del *.obj
	-del *_.c
	-del *.h
	-del *.ilk
	-del *.map
1420
1421
1422
1423
1424
1425
1426




1427
1428
1429
1430
1431
1432
1433
	-del translate$P
	-del mkindex$E
	-del mkindex$P
	-del makeheaders$E
	-del makeheaders$P
	-del mkversion$E
	-del mkversion$P





$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h







>
>
>
>







1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
	-del translate$P
	-del mkindex$E
	-del mkindex$P
	-del makeheaders$E
	-del makeheaders$P
	-del mkversion$E
	-del mkversion$P
	-del codecheck1$E
	-del codecheck1$P
	-del mkbuiltin$E
	-del mkbuiltin$P

$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
  writeln "${s}_.c : \$(SRCDIR)\\$s.c"
  writeln "\ttranslate\$E \$** > \$@\n"
}

writeln "fossil.res : \$B\\win\\fossil.rc"
writeln "\t\$(RCC)  /fo \$@ \$**\n"

writeln "headers: makeheaders\$E page_index.h VERSION.h"
writeln -nonewline "\tmakeheaders\$E "
set i 0
foreach s [lsort $src] {
  if {$i > 0} {
    writeln " \\"
    writeln -nonewline "\t\t\t"
  }







|







1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
  writeln "${s}_.c : \$(SRCDIR)\\$s.c"
  writeln "\ttranslate\$E \$** > \$@\n"
}

writeln "fossil.res : \$B\\win\\fossil.rc"
writeln "\t\$(RCC)  /fo \$@ \$**\n"

writeln "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h"
writeln -nonewline "\tmakeheaders\$E "
set i 0
foreach s [lsort $src] {
  if {$i > 0} {
    writeln " \\"
    writeln -nonewline "\t\t\t"
  }
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
# define commands for building the windows resource files
RESOURCE=fossil.res
RC=$(PellesCDir)\bin\porc.exe
RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)

# define the special utilities files, needed to generate
# the automatically generated source files
UTILS=translate.exe mkindex.exe makeheaders.exe
UTILS_OBJ=$(UTILS:.exe=.obj)
UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))

# define the SQLite files, which need special flags on compile
SQLITESRC=sqlite3.c
ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))







|







1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
# define commands for building the windows resource files
RESOURCE=fossil.res
RC=$(PellesCDir)\bin\porc.exe
RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)

# define the special utilities files, needed to generate
# the automatically generated source files
UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
UTILS_OBJ=$(UTILS:.exe=.obj)
UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))

# define the SQLite files, which need special flags on compile
SQLITESRC=sqlite3.c
ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)

# main target file is the application
APPLICATION=fossil.exe

# define the standard make target
.PHONY:	default
default:	page_index.h headers $(APPLICATION)

# symbolic target to generate the source generate utils
.PHONY:	utils
utils:	$(UTILS)

# link utils
$(UTILS) version.exe:	%.exe:	%.obj







|







1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)

# main target file is the application
APPLICATION=fossil.exe

# define the standard make target
.PHONY:	default
default:	page_index.h builtin_data.h headers $(APPLICATION)

# symbolic target to generate the source generate utils
.PHONY:	utils
utils:	$(UTILS)

# link utils
$(UTILS) version.exe:	%.exe:	%.obj
1621
1622
1623
1624
1625
1626
1627



1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
# generate the translated c-source files
$(TRANSLATEDSRC):	%_.c:	$(SRCDIR)%.c translate.exe
	translate.exe $< >$@

# generate the index source, containing all web references,..
page_index.h:	$(TRANSLATEDSRC) mkindex.exe
	mkindex.exe $(TRANSLATEDSRC) >$@




# extracting version info from manifest
VERSION.h:	version.exe ..\manifest.uuid ..\manifest ..\VERSION
	version.exe ..\manifest.uuid ..\manifest ..\VERSION  > $@

# generate the simplified headers
headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
	makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
	echo Done >$@

# compile C sources with relevant options

$(TRANSLATEDOBJ):	%_.obj:	%_.c %.h
	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"







>
>
>



|


|







1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
# generate the translated c-source files
$(TRANSLATEDSRC):	%_.c:	$(SRCDIR)%.c translate.exe
	translate.exe $< >$@

# generate the index source, containing all web references,..
page_index.h:	$(TRANSLATEDSRC) mkindex.exe
	mkindex.exe $(TRANSLATEDSRC) >$@

builtin_data.h:	$(EXTRA_FILES) mkbuiltin.exe
	mkbuiltin.exe $(EXTRA_FILES) >$@

# extracting version info from manifest
VERSION.h:	version.exe ..\manifest.uuid ..\manifest ..\VERSION
	version.exe ..\manifest.uuid ..\manifest ..\VERSION  >$@

# generate the simplified headers
headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
	makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
	echo Done >$@

# compile C sources with relevant options

$(TRANSLATEDOBJ):	%_.obj:	%_.c %.h
	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
Changes to src/manifest.c.
45
46
47
48
49
50
51

52
53
54
55
56
57
58
#define PERM_LNK          2     /*  symlink       */

/*
** Flags for use with manifest_crosslink().
*/
#define MC_NONE           0  /*  default handling           */
#define MC_PERMIT_HOOKS   1  /*  permit hooks to execute    */


/*
** A single F-card within a manifest
*/
struct ManifestFile {
  char *zName;           /* Name of a file */
  char *zUuid;           /* UUID of the file */







>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define PERM_LNK          2     /*  symlink       */

/*
** Flags for use with manifest_crosslink().
*/
#define MC_NONE           0  /*  default handling           */
#define MC_PERMIT_HOOKS   1  /*  permit hooks to execute    */
#define MC_NO_ERRORS      2  /*  do not issue errors for a bad parse */

/*
** A single F-card within a manifest
*/
struct ManifestFile {
  char *zName;           /* Name of a file */
  char *zUuid;           /* UUID of the file */
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
  char cPrevType = 0;
  char cType;
  char *z;
  int n;
  char *zUuid;
  int sz = 0;
  int isRepeat, hasSelfRefTag = 0;

  static Bag seen;
  const char *zErr = 0;

  if( rid==0 ){
    isRepeat = 1;
  }else if( bag_find(&seen, rid) ){
    isRepeat = 1;
  }else{
    isRepeat = 0;
    bag_insert(&seen, rid);
  }

  /* Every control artifact ends with a '\n' character.  Exit early
  ** if that is not the case for this artifact.
  */
  if( !isRepeat ) g.parseCnt[0]++;
  z = blob_materialize(pContent);
  n = blob_size(pContent);
  if( n<=0 || z[n-1]!='\n' ){
    blob_reset(pContent);
    blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length");
    return 0;
  }

  /* Strip off the PGP signature if there is one.
  */
  remove_pgp_signature(&z, &n);








>


















|

|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  char cPrevType = 0;
  char cType;
  char *z;
  int n;
  char *zUuid;
  int sz = 0;
  int isRepeat, hasSelfRefTag = 0;
  Blob bUuid = BLOB_INITIALIZER;
  static Bag seen;
  const char *zErr = 0;

  if( rid==0 ){
    isRepeat = 1;
  }else if( bag_find(&seen, rid) ){
    isRepeat = 1;
  }else{
    isRepeat = 0;
    bag_insert(&seen, rid);
  }

  /* Every control artifact ends with a '\n' character.  Exit early
  ** if that is not the case for this artifact.
  */
  if( !isRepeat ) g.parseCnt[0]++;
  z = blob_materialize(pContent);
  n = blob_size(pContent);
  if( pErr && (n<=0 || z[n-1]!='\n') ){
    blob_reset(pContent);
    blob_append(pErr, n ? "not terminated with \\n" : "zero-length", -1);
    return 0;
  }

  /* Strip off the PGP signature if there is one.
  */
  remove_pgp_signature(&z, &n);

401
402
403
404
405
406
407





408
409
410
411
412
413
414
  /* Then verify the Z-card.
  */
  if( verify_z_card(z, n)==2 ){
    blob_reset(pContent);
    blob_appendf(pErr, "incorrect Z-card cksum");
    return 0;
  }






  /* Allocate a Manifest object to hold the parsed control artifact.
  */
  p = fossil_malloc( sizeof(*p) );
  memset(p, 0, sizeof(*p));
  memcpy(&p->content, pContent, sizeof(p->content));
  p->rid = rid;







>
>
>
>
>







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  /* Then verify the Z-card.
  */
  if( verify_z_card(z, n)==2 ){
    blob_reset(pContent);
    blob_appendf(pErr, "incorrect Z-card cksum");
    return 0;
  }

  /* Store the UUID (before modifying the blob) only for error
  ** reporting purposes.
  */
  sha1sum_blob(pContent, &bUuid);

  /* Allocate a Manifest object to hold the parsed control artifact.
  */
  p = fossil_malloc( sizeof(*p) );
  memset(p, 0, sizeof(*p));
  memcpy(&p->content, pContent, sizeof(p->content));
  p->rid = rid;
942
943
944
945
946
947
948

949
950
951




952
953
954
955
956
957
958
    if( p->rDate<=0.0 ) SYNTAX("missing date on control");
    if( p->zMimetype ) SYNTAX("N-card in control");
    if( !seenZ ) SYNTAX("missing Z-card on control");
    p->type = CFTYPE_CONTROL;
  }
  md5sum_init();
  if( !isRepeat ) g.parseCnt[p->type]++;

  return p;

manifest_syntax_error:




  if( zErr ){
    blob_appendf(pErr, "line %d: %s", lineNo, zErr);
  }else{
    blob_appendf(pErr, "unknown error on line %d", lineNo);
  }
  md5sum_init();
  manifest_destroy(p);







>



>
>
>
>







949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
    if( p->rDate<=0.0 ) SYNTAX("missing date on control");
    if( p->zMimetype ) SYNTAX("N-card in control");
    if( !seenZ ) SYNTAX("missing Z-card on control");
    p->type = CFTYPE_CONTROL;
  }
  md5sum_init();
  if( !isRepeat ) g.parseCnt[p->type]++;
  blob_reset(&bUuid);
  return p;

manifest_syntax_error:
  if(bUuid.nUsed){
    blob_appendf(pErr, "manifest [%.40s] ", blob_str(&bUuid));
    blob_reset(&bUuid);
  }
  if( zErr ){
    blob_appendf(pErr, "line %d: %s", lineNo, zErr);
  }else{
    blob_appendf(pErr, "unknown error on line %d", lineNo);
  }
  md5sum_init();
  manifest_destroy(p);
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
  blob_zero(&brief);
  if( once ){
    once = 0;
    zTitleExpr = db_get("ticket-title-expr", "title");
    zStatusColumn = db_get("ticket-status-column", "status");
  }
  zTitle = db_text("unknown",
    "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
    zTitleExpr, pManifest->zTicketUuid
  );
  if( !isNew ){
    for(i=0; i<pManifest->nField; i++){
      if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
        zNewStatus = pManifest->aField[i].zValue;
      }
    }
    if( zNewStatus ){
      blob_appendf(&comment, "%h ticket [%s|%S]: <i>%h</i>",
         zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle
      );
      if( pManifest->nField>1 ){
        blob_appendf(&comment, " plus %d other change%s",
          pManifest->nField-1, pManifest->nField==2 ? "" : "s");
      }
      blob_appendf(&brief, "%h ticket [%s|%S].",
                   zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
    }else{
      zNewStatus = db_text("unknown",
         "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
         zStatusColumn, pManifest->zTicketUuid
      );
      blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
           "%d other change%s",
           pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
           pManifest->nField, pManifest->nField==1 ? "" : "s"
      );







|




















|







1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
  blob_zero(&brief);
  if( once ){
    once = 0;
    zTitleExpr = db_get("ticket-title-expr", "title");
    zStatusColumn = db_get("ticket-status-column", "status");
  }
  zTitle = db_text("unknown",
    "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
    zTitleExpr, pManifest->zTicketUuid
  );
  if( !isNew ){
    for(i=0; i<pManifest->nField; i++){
      if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
        zNewStatus = pManifest->aField[i].zValue;
      }
    }
    if( zNewStatus ){
      blob_appendf(&comment, "%h ticket [%s|%S]: <i>%h</i>",
         zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle
      );
      if( pManifest->nField>1 ){
        blob_appendf(&comment, " plus %d other change%s",
          pManifest->nField-1, pManifest->nField==2 ? "" : "s");
      }
      blob_appendf(&brief, "%h ticket [%s|%S].",
                   zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
    }else{
      zNewStatus = db_text("unknown",
         "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
         zStatusColumn, pManifest->zTicketUuid
      );
      blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
           "%d other change%s",
           pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
           pManifest->nField, pManifest->nField==1 ? "" : "s"
      );
1731
1732
1733
1734
1735
1736
1737

1738


1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749

1750


1751
1752
1753
1754
1755
1756
1757
  const char *zScript = 0;
  const char *zUuid = 0;

  if( (p = manifest_cache_find(rid))!=0 ){
    blob_reset(pContent);
  }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
    assert( blob_is_reset(pContent) || pContent==0 );

    fossil_error(1, "syntax error in manifest");


    return 0;
  }
  if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
    manifest_destroy(p);
    assert( blob_is_reset(pContent) );
    fossil_error(1, "no manifest");
    return 0;
  }
  if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
    manifest_destroy(p);
    assert( blob_is_reset(pContent) );

    fossil_error(1, "cannot fetch baseline manifest");


    return 0;
  }
  db_begin_transaction();
  if( p->type==CFTYPE_MANIFEST ){
    if( permitHooks ){
      zScript = xfer_commit_code();
      zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);







>
|
>
>





|





>
|
>
>







1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
  const char *zScript = 0;
  const char *zUuid = 0;

  if( (p = manifest_cache_find(rid))!=0 ){
    blob_reset(pContent);
  }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
    assert( blob_is_reset(pContent) || pContent==0 );
    if( (flags & MC_NO_ERRORS)==0 ){
      fossil_error(1, "syntax error in manifest [%s]",
                   db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
    }
    return 0;
  }
  if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
    manifest_destroy(p);
    assert( blob_is_reset(pContent) );
    if( (flags & MC_NO_ERRORS)==0 ) fossil_error(1, "no manifest");
    return 0;
  }
  if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
    manifest_destroy(p);
    assert( blob_is_reset(pContent) );
    if( (flags & MC_NO_ERRORS)==0 ){
      fossil_error(1, "cannot fetch baseline for manifest [%s]",
                   db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
    }
    return 0;
  }
  db_begin_transaction();
  if( p->type==CFTYPE_MANIFEST ){
    if( permitHooks ){
      zScript = xfer_commit_code();
      zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
      "                  bgcolor,euser,ecomment)"
      "VALUES('w',%.17g,%d,%Q,%Q,"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
      p->rDate, rid, p->zUser, zComment,
      TAG_BGCOLOR, rid,
      TAG_BGCOLOR, rid,
      TAG_USER, rid,
      TAG_COMMENT, rid
    );
    fossil_free(zComment);
  }
  if( p->type==CFTYPE_EVENT ){
    char *zTag = mprintf("event-%s", p->zEventId);







<







1910
1911
1912
1913
1914
1915
1916

1917
1918
1919
1920
1921
1922
1923
      "                  bgcolor,euser,ecomment)"
      "VALUES('w',%.17g,%d,%Q,%Q,"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
      p->rDate, rid, p->zUser, zComment,
      TAG_BGCOLOR, rid,

      TAG_USER, rid,
      TAG_COMMENT, rid
    );
    fossil_free(zComment);
  }
  if( p->type==CFTYPE_EVENT ){
    char *zTag = mprintf("event-%s", p->zEventId);
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
      if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){
        blob_appendf(&comment,
           " Edit [%s|%S]:",
           zTagUuid, zTagUuid);
        branchMove = 0;
        if( permitHooks && db_exists("SELECT 1 FROM event, blob"
            " WHERE event.type='ci' AND event.objid=blob.rid"
            " AND blob.uuid='%s'", zTagUuid) ){
          zScript = xfer_commit_code();
          zUuid = zTagUuid;
        }
      }
      zName = p->aTag[i].zName;
      zValue = p->aTag[i].zValue;
      if( strcmp(zName, "*branch")==0 ){







|







2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
      if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){
        blob_appendf(&comment,
           " Edit [%s|%S]:",
           zTagUuid, zTagUuid);
        branchMove = 0;
        if( permitHooks && db_exists("SELECT 1 FROM event, blob"
            " WHERE event.type='ci' AND event.objid=blob.rid"
            " AND blob.uuid=%Q", zTagUuid) ){
          zScript = xfer_commit_code();
          zUuid = zTagUuid;
        }
      }
      zName = p->aTag[i].zName;
      zValue = p->aTag[i].zValue;
      if( strcmp(zName, "*branch")==0 ){
Changes to src/markdown_html.c.
80
81
82
83
84
85
86










87
88
89
90
91
92
93
      i++;
    }
  }
}


/* HTML block tags */











static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){
  char *data = blob_buffer(text);
  size_t first = 0, size = blob_size(text);
  INTER_BLOCK(ob);
  while( first<size && data[first]=='\n' ) first++;
  while( size>first && data[size-1]=='\n' ) size--;







>
>
>
>
>
>
>
>
>
>







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
      i++;
    }
  }
}


/* HTML block tags */

static void html_prolog(struct Blob *ob, void *opaque){
  INTER_BLOCK(ob);
  BLOB_APPEND_LITTERAL(ob, "<div class=\"markdown\">\n");
}

static void html_epilog(struct Blob *ob, void *opaque){
  INTER_BLOCK(ob);
  BLOB_APPEND_LITTERAL(ob, "</div>\n");
}

static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){
  char *data = blob_buffer(text);
  size_t first = 0, size = blob_size(text);
  INTER_BLOCK(ob);
  while( first<size && data[first]=='\n' ) first++;
  while( size>first && data[size-1]=='\n' ) size--;
362
363
364
365
366
367
368
369


370
371
372
373
374
375
376

void markdown_to_html(
  struct Blob *input_markdown,
  struct Blob *output_title,
  struct Blob *output_body
){
  struct mkd_renderer html_renderer = {
    0, 0,  /* no prolog or epilog */



    /* block level elements */
    html_blockcode,
    html_blockquote,
    html_raw_block,
    html_header,
    html_hrule,







|
>
>







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

void markdown_to_html(
  struct Blob *input_markdown,
  struct Blob *output_title,
  struct Blob *output_body
){
  struct mkd_renderer html_renderer = {
    /* prolog and epilog */
    html_prolog,
    html_epilog,

    /* block level elements */
    html_blockcode,
    html_blockquote,
    html_raw_block,
    html_header,
    html_hrule,
Changes to src/merge3.c.
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
      */
      int sz = 1;    /* Size of the conflict in lines */
      nConflict++;
      while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
        sz++;
      }
      DEBUG( printf("CONFLICT %d\n", sz); )
      blob_appendf(pOut, mergeMarker[0]);
      i1 = output_one_side(pOut, pV1, aC1, i1, sz);
      blob_appendf(pOut, mergeMarker[1]);
      blob_copy_lines(pOut, pPivot, sz);
      blob_appendf(pOut, mergeMarker[2]);
      i2 = output_one_side(pOut, pV2, aC2, i2, sz);
      blob_appendf(pOut, mergeMarker[3]);
   }

    /* If we are finished with an edit triple, advance to the next
    ** triple.
    */
    if( i1<limit1 && aC1[i1]==0 && aC1[i1+1]==0 && aC1[i1+2]==0 ) i1+=3;
    if( i2<limit2 && aC2[i2]==0 && aC2[i2+1]==0 && aC2[i2+2]==0 ) i2+=3;







|

|

|

|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
      */
      int sz = 1;    /* Size of the conflict in lines */
      nConflict++;
      while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
        sz++;
      }
      DEBUG( printf("CONFLICT %d\n", sz); )
      blob_append(pOut, mergeMarker[0], -1);
      i1 = output_one_side(pOut, pV1, aC1, i1, sz);
      blob_append(pOut, mergeMarker[1], -1);
      blob_copy_lines(pOut, pPivot, sz);
      blob_append(pOut, mergeMarker[2], -1);
      i2 = output_one_side(pOut, pV2, aC2, i2, sz);
      blob_append(pOut, mergeMarker[3], -1);
   }

    /* If we are finished with an edit triple, advance to the next
    ** triple.
    */
    if( i1<limit1 && aC1[i1]==0 && aC1[i1+1]==0 && aC1[i1+2]==0 ) i1+=3;
    if( i2<limit2 && aC2[i2]==0 && aC2[i2+1]==0 && aC2[i2+2]==0 ) i2+=3;
Added src/mkbuiltin.c.


































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
** Copyright (c) 2014 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)

** 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.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This is a stand-alone utility program that is part of the Fossil build
** process.  This program reads files named on the command line and converts
** them into ANSI-C static char array variables.  Output is written onto
** standard output.
**
** The makefiles use this utility package various resources (large scripts,
** GIF images, etc) that are separate files in the source code as byte
** arrays in the resulting executable.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*
** Read the entire content of the file named zFilename into memory obtained
** from malloc() and retur a pointer to that memory.  Write the size of the
** file into *pnByte.
*/
static unsigned char *read_file(const char *zFilename, int *pnByte){
  FILE *in;
  unsigned char *z;
  int nByte;
  int got;
  in = fopen(zFilename, "rb");
  if( in==0 ){
    return 0;
  }
  fseek(in, 0, SEEK_END);
  *pnByte = nByte = ftell(in);
  fseek(in, 0, SEEK_SET);
  z = malloc( nByte+1 );
  if( z==0 ){
    fprintf(stderr, "failed to allocate %d bytes\n", nByte+1);
    exit(1);
  }
  got = fread(z, 1, nByte, in);
  fclose(in);
  z[got] = 0;
  return z;
}

/*
** There is an instance of the following for each file translated.
*/
typedef struct Resource Resource;
struct Resource {
  const char *zName;
  int nByte;
};

/*
** Compare two Resource objects for sorting purposes.  They sort
** in zName order so that Fossil can search for resources using
** a binary search.
*/
static int compareResource(const void *a, const void *b){
  Resource *pA = (Resource*)a;
  Resource *pB = (Resource*)b;
  return strcmp(pA->zName, pB->zName);
}

int main(int argc, char **argv){
  int i, sz;
  int j, n;
  Resource *aRes;
  int nRes = argc-1;
  unsigned char *pData;
  int nErr = 0;
  
  aRes = malloc( nRes*sizeof(aRes[0]) );
  if( aRes==0 ){
    fprintf(stderr, "malloc failed\n");
    return 1;
  }
  for(i=0; i<argc-1; i++){
    aRes[i].zName = argv[i+1];
  }
  qsort(aRes, nRes, sizeof(aRes[0]), compareResource);
  printf("/* Automatically generated code:  Do not edit.\n**\n"
         "** Rerun the \"mkbuiltin.c\" program or rerun the Fossil\n"
         "** makefile to update this source file.\n"
         "*/\n");
  for(i=0; i<nRes; i++){
    pData = read_file(aRes[i].zName, &sz);
    if( pData==0 ){
      fprintf(stderr, "Cannot open file [%s]\n", aRes[i].zName);
      nErr++;
      continue;
    }
    aRes[i].nByte = sz;
    printf("/* Content of file %s */\n", aRes[i].zName);
    printf("static const unsigned char bidata%d[%d] = {\n  ",
           i, sz+1);
    for(j=n=0; j<=sz; j++){
      printf("%3d", pData[j]);
      if( j==sz ){
        printf(" };\n");
      }else if( n==14 ){
        printf(",\n  ");
        n = 0;
      }else{
        printf(", ");
        n++;
      }
    }
    free(pData);
  }
  printf("typedef struct BuiltinFileTable BuiltinFileTable;\n");
  printf("struct BuiltinFileTable {\n");
  printf("  const char *zName;\n");
  printf("  const unsigned char *pData;\n");
  printf("  int nByte;\n");
  printf("};\n");
  printf("static const BuiltinFileTable aBuiltinFiles[] = {\n");
  for(i=0; i<nRes; i++){
    const char *zTail;
    const char *z = aRes[i].zName;
    zTail = z;
    while( z && z[0] ){
      if( z[0]=='/' || z[0]=='\\' ) zTail = &z[1];
      z++;
    }
    printf("  { \"%s\", bidata%d, %d },\n", zTail, i, aRes[i].nByte);
  }
  printf("};\n");
  return nErr;
}
Changes to src/moderate.c.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
     "mlink",      "mid",
     "mlink",      "fid",
     "tagxref",    "srcid",
     "tagxref",    "rid",
  };
  int i;
  for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
    if( db_exists("SELECT 1 FROM %s WHERE %s=%d",
                  aTabField[i], aTabField[i+1], rid) ) return 1;
  }
  return 0;
}

/*
** Delete a moderation item given by objid







|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
     "mlink",      "mid",
     "mlink",      "fid",
     "tagxref",    "srcid",
     "tagxref",    "rid",
  };
  int i;
  for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
    if( db_exists("SELECT 1 FROM \"%w\" WHERE \"%w\"=%d",
                  aTabField[i], aTabField[i+1], rid) ) return 1;
  }
  return 0;
}

/*
** Delete a moderation item given by objid
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

  login_check_credentials();
  if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
  style_header("Pending Moderation Requests");
  @ <h2>All Pending Moderation Requests</h2>
  if( moderation_table_exists() ){
    blob_init(&sql, timeline_query_for_www(), -1);
    blob_appendf(&sql,
        " AND event.objid IN (SELECT objid FROM modreq)"
        " ORDER BY event.mtime DESC"
    );
    db_prepare(&q, blob_str(&sql));
    www_print_timeline(&q, 0, 0, 0, 0);
    db_finalize(&q);
  }
  style_footer();
}







|



|





150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

  login_check_credentials();
  if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
  style_header("Pending Moderation Requests");
  @ <h2>All Pending Moderation Requests</h2>
  if( moderation_table_exists() ){
    blob_init(&sql, timeline_query_for_www(), -1);
    blob_append_sql(&sql,
        " AND event.objid IN (SELECT objid FROM modreq)"
        " ORDER BY event.mtime DESC"
    );
    db_prepare(&q, "%s", blob_sql_text(&sql));
    www_print_timeline(&q, 0, 0, 0, 0);
    db_finalize(&q);
  }
  style_footer();
}
Changes to src/name.c.
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  if( nTag>=4 && nTag<=UUID_SIZE && validate16(zTag, nTag) ){
    Stmt q;
    char zUuid[UUID_SIZE+1];
    memcpy(zUuid, zTag, nTag+1);
    canonical16(zUuid, nTag);
    rid = 0;
    if( zType[0]=='*' ){
      db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zUuid);
    }else{
      db_prepare(&q,
        "SELECT blob.rid"
        "  FROM blob, event"
        " WHERE blob.uuid GLOB '%s*'"
        "   AND event.objid=blob.rid"
        "   AND event.type GLOB '%q'",
        zUuid, zType
      );
    }
    if( db_step(&q)==SQLITE_ROW ){
      rid = db_column_int(&q, 0);







|




|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  if( nTag>=4 && nTag<=UUID_SIZE && validate16(zTag, nTag) ){
    Stmt q;
    char zUuid[UUID_SIZE+1];
    memcpy(zUuid, zTag, nTag+1);
    canonical16(zUuid, nTag);
    rid = 0;
    if( zType[0]=='*' ){
      db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid);
    }else{
      db_prepare(&q,
        "SELECT blob.rid"
        "  FROM blob, event"
        " WHERE blob.uuid GLOB '%q*'"
        "   AND event.objid=blob.rid"
        "   AND event.type GLOB '%q'",
        zUuid, zType
      );
    }
    if( db_step(&q)==SQLITE_ROW ){
      rid = db_column_int(&q, 0);
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
      if( strcmp(zType,"*")==0 ){
        rid = atoi(zTag);
      }else{
        rid = db_int(0,
          "SELECT event.objid"
          "  FROM event"
          " WHERE event.objid=%s"
          "   AND event.type GLOB '%q'", zTag, zType);
      }
    }
  }
  return rid;
}

/*







|







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
      if( strcmp(zType,"*")==0 ){
        rid = atoi(zTag);
      }else{
        rid = db_int(0,
          "SELECT event.objid"
          "  FROM event"
          " WHERE event.objid=%s"
          "   AND event.type GLOB '%q'", zTag /*safe-for-%s*/, zType);
      }
    }
  }
  return rid;
}

/*
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
  /* Report any HIDDEN, PRIVATE, CLUSTER, or CLOSED tags on this artifact */
  db_prepare(&q,
    "SELECT tagname"
    "  FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
    " WHERE tagxref.rid=%d"
    "   AND tag.tagid IN (5,6,7,9)"
    " ORDER BY 1",
    rid, rid
  );
  cnt = 0;
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPrefix = cnt++ ? ", " : "raw-tags:   ";
    fossil_print("%s%s", zPrefix, db_column_text(&q,0));
  }
  if( cnt ) fossil_print("\n");







|







552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
  /* Report any HIDDEN, PRIVATE, CLUSTER, or CLOSED tags on this artifact */
  db_prepare(&q,
    "SELECT tagname"
    "  FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
    " WHERE tagxref.rid=%d"
    "   AND tag.tagid IN (5,6,7,9)"
    " ORDER BY 1",
    rid
  );
  cnt = 0;
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPrefix = cnt++ ? ", " : "raw-tags:   ";
    fossil_print("%s%s", zPrefix, db_column_text(&q,0));
  }
  if( cnt ) fossil_print("\n");
Changes to src/path.c.
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

/*
** Compute the shortest path from iFrom to iTo
**
** If directOnly is true, then use only the "primary" links from parent to
** child.  In other words, ignore merges.
**
** Return a pointer to the beginning of the path (the iFrom node).  
** Elements of the path can be traversed by following the PathNode.u.pTo
** pointer chain.
**
** Return NULL if no path is found.
*/
PathNode *path_shortest(
  int iFrom,          /* Path starts here */







|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

/*
** Compute the shortest path from iFrom to iTo
**
** If directOnly is true, then use only the "primary" links from parent to
** child.  In other words, ignore merges.
**
** Return a pointer to the beginning of the path (the iFrom node).
** Elements of the path can be traversed by following the PathNode.u.pTo
** pointer chain.
**
** Return NULL if no path is found.
*/
PathNode *path_shortest(
  int iFrom,          /* Path starts here */
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  path_reset();
  path.pStart = path_new_node(iFrom, 0, 0);
  if( iTo==iFrom ){
    path.pEnd = path.pStart;
    return path.pStart;
  }
  if( oneWayOnly && directOnly ){
    db_prepare(&s, 
        "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
    );
  }else if( oneWayOnly ){
    db_prepare(&s, 
        "SELECT cid, 1 FROM plink WHERE pid=:pid "
    );
  }else if( directOnly ){
    db_prepare(&s, 
        "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
        "UNION ALL "
        "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
    );
  }else{
    db_prepare(&s, 
        "SELECT cid, 1 FROM plink WHERE pid=:pid "
        "UNION ALL "
        "SELECT pid, 0 FROM plink WHERE cid=:pid"
    );
  }
  while( path.pCurrent ){
    path.nStep++;







|



|



|





|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  path_reset();
  path.pStart = path_new_node(iFrom, 0, 0);
  if( iTo==iFrom ){
    path.pEnd = path.pStart;
    return path.pStart;
  }
  if( oneWayOnly && directOnly ){
    db_prepare(&s,
        "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
    );
  }else if( oneWayOnly ){
    db_prepare(&s,
        "SELECT cid, 1 FROM plink WHERE pid=:pid "
    );
  }else if( directOnly ){
    db_prepare(&s,
        "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
        "UNION ALL "
        "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
    );
  }else{
    db_prepare(&s,
        "SELECT cid, 1 FROM plink WHERE pid=:pid "
        "UNION ALL "
        "SELECT pid, 0 FROM plink WHERE cid=:pid"
    );
  }
  while( path.pCurrent ){
    path.nStep++;
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
      "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)"
      "  FROM blob, event"
      " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
      p->rid, p->rid);
    fossil_print("%4d: %5d %s", n, p->rid, z);
    fossil_free(z);
    if( p->u.pTo ){
      fossil_print(" is a %s of\n", 
                   p->u.pTo->fromIsParent ? "parent" : "child");
    }else{
      fossil_print("\n");
    }
  }
}








|







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
      "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)"
      "  FROM blob, event"
      " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
      p->rid, p->rid);
    fossil_print("%4d: %5d %s", n, p->rid, z);
    fossil_free(z);
    if( p->u.pTo ){
      fossil_print(" is a %s of\n",
                   p->u.pTo->fromIsParent ? "parent" : "child");
    }else{
      fossil_print("\n");
    }
  }
}

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
};

/*
** Compute all file name changes that occur going from checkin iFrom
** to checkin iTo.
**
** The number of name changes is written into *pnChng.  For each name
** change, two integers are allocated for *piChng.  The first is the 
** filename.fnid for the original name as seen in check-in iFrom and
** the second is for new name as it is used in check-in iTo.
**
** Space to hold *piChng is obtained from fossil_malloc() and should
** be released by the caller.
**
** This routine really has nothing to do with path.  It is located







|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
};

/*
** Compute all file name changes that occur going from checkin iFrom
** to checkin iTo.
**
** The number of name changes is written into *pnChng.  For each name
** change, two integers are allocated for *piChng.  The first is the
** filename.fnid for the original name as seen in check-in iFrom and
** the second is for new name as it is used in check-in iTo.
**
** Space to hold *piChng is obtained from fossil_malloc() and should
** be released by the caller.
**
** This routine really has nothing to do with path.  It is located
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
    fossil_free(aChng);
    g.argv += 2;
    g.argc -= 2;
  }
}

/* Query to extract all rename operations */
static const char zRenameQuery[] = 
@ SELECT
@     datetime(event.mtime),
@     F.name AS old_name,
@     T.name AS new_name,
@     blob.uuid
@   FROM mlink, filename F, filename T, event, blob
@  WHERE coalesce(mlink.pfnid,0)!=0 AND mlink.pfnid!=mlink.fnid
@    AND F.fnid=mlink.pfnid
@    AND T.fnid=mlink.fnid
@    AND event.objid=mlink.mid
@    AND event.type='ci'
@    AND blob.rid=mlink.mid
@  ORDER BY 1 DESC, 2;
;
  
/*
** WEBPAGE: test-rename-list
**
** Print a list of all file rename operations throughout history.
** This page is intended for for testing purposes only and may change
** or be discontinued without notice.
*/
void test_rename_list_page(void){
  Stmt q;

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  style_header("List Of File Name Changes");
  @ <h3>NB: Experimental Page</h3>
  @ <table border="1" width="100%%">
  @ <tr><th>Date &amp; Time</th>
  @ <th>Old Name</th>
  @ <th>New Name</th>
  @ <th>Check-in</th></tr>
  db_prepare(&q, zRenameQuery);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zDate = db_column_text(&q, 0);
    const char *zOld = db_column_text(&q, 1);
    const char *zNew = db_column_text(&q, 2);
    const char *zUuid = db_column_text(&q, 3);
    @ <tr>
    @ <td>%z(href("%R/timeline?c=%t",zDate))%s(zDate)</a></td>







|














|



















|







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
    fossil_free(aChng);
    g.argv += 2;
    g.argc -= 2;
  }
}

/* Query to extract all rename operations */
static const char zRenameQuery[] =
@ SELECT
@     datetime(event.mtime),
@     F.name AS old_name,
@     T.name AS new_name,
@     blob.uuid
@   FROM mlink, filename F, filename T, event, blob
@  WHERE coalesce(mlink.pfnid,0)!=0 AND mlink.pfnid!=mlink.fnid
@    AND F.fnid=mlink.pfnid
@    AND T.fnid=mlink.fnid
@    AND event.objid=mlink.mid
@    AND event.type='ci'
@    AND blob.rid=mlink.mid
@  ORDER BY 1 DESC, 2;
;

/*
** WEBPAGE: test-rename-list
**
** Print a list of all file rename operations throughout history.
** This page is intended for for testing purposes only and may change
** or be discontinued without notice.
*/
void test_rename_list_page(void){
  Stmt q;

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  style_header("List Of File Name Changes");
  @ <h3>NB: Experimental Page</h3>
  @ <table border="1" width="100%%">
  @ <tr><th>Date &amp; Time</th>
  @ <th>Old Name</th>
  @ <th>New Name</th>
  @ <th>Check-in</th></tr>
  db_prepare(&q, "%s", zRenameQuery/*safe-for-%s*/);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zDate = db_column_text(&q, 0);
    const char *zOld = db_column_text(&q, 1);
    const char *zNew = db_column_text(&q, 2);
    const char *zUuid = db_column_text(&q, 3);
    @ <tr>
    @ <td>%z(href("%R/timeline?c=%t",zDate))%s(zDate)</a></td>
Changes to src/printf.c.
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#define etERROR      10 /* Used to indicate no such conversion type */
/* The rest are extensions, not normally found in printf() */
#define etBLOB       11 /* Blob objects.  %b */
#define etBLOBSQL    12 /* Blob objects quoted for SQL.  %B */
#define etSQLESCAPE  13 /* Strings with '\'' doubled.  %q */
#define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
                          NULL pointers replaced by SQL NULL.  %Q */

#define etPOINTER    15 /* The %p conversion */
#define etHTMLIZE    16 /* Make text safe for HTML */
#define etHTTPIZE    17 /* Make text safe for HTTP.  "/" encoded as %2f */
#define etURLIZE     18 /* Make text safe for HTTP.  "/" not encoded */
#define etFOSSILIZE  19 /* The fossil header encoding format. */
#define etPATH       20 /* Path type */
#define etWIKISTR    21 /* Timeline comment text rendered from a char*: %w */
#define etSTRINGID   23 /* String with length limit for a UUID prefix: %S */
#define etROOT       24 /* String value of g.zTop: % */


/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;








>
|
|
|
|
|
|
|

|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#define etERROR      10 /* Used to indicate no such conversion type */
/* The rest are extensions, not normally found in printf() */
#define etBLOB       11 /* Blob objects.  %b */
#define etBLOBSQL    12 /* Blob objects quoted for SQL.  %B */
#define etSQLESCAPE  13 /* Strings with '\'' doubled.  %q */
#define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
                          NULL pointers replaced by SQL NULL.  %Q */
#define etSQLESCAPE3 15 /* Double '"' characters within an indentifier.  %w */
#define etPOINTER    16 /* The %p conversion */
#define etHTMLIZE    17 /* Make text safe for HTML */
#define etHTTPIZE    18 /* Make text safe for HTTP.  "/" encoded as %2f */
#define etURLIZE     19 /* Make text safe for HTTP.  "/" not encoded */
#define etFOSSILIZE  20 /* The fossil header encoding format. */
#define etPATH       21 /* Path type */
#define etWIKISTR    22 /* Timeline comment text rendered from a char*: %W */
#define etSTRINGID   23 /* String with length limit for a UUID prefix: %S */
#define etROOT       24 /* String value of g.zTop: %R */


/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;

94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'b',  0, 2, etBLOB,       0,  0 },
  {  'B',  0, 2, etBLOBSQL,    0,  0 },
  {  'w',  0, 2, etWIKISTR,    0,  0 },
  {  'h',  0, 4, etHTMLIZE,    0,  0 },
  {  'R',  0, 0, etROOT,       0,  0 },
  {  't',  0, 4, etHTTPIZE,    0,  0 },  /* "/" -> "%2F" */
  {  'T',  0, 4, etURLIZE,     0,  0 },  /* "/" unchanged */

  {  'F',  0, 4, etFOSSILIZE,  0,  0 },
  {  'S',  0, 4, etSTRINGID,   0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
  {  'o',  8, 0, etRADIX,      0,  2 },
  {  'u', 10, 0, etRADIX,      0,  0 },
  {  'x', 16, 0, etRADIX,      16, 1 },
  {  'X', 16, 0, etRADIX,      0,  4 },







|




>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'b',  0, 2, etBLOB,       0,  0 },
  {  'B',  0, 2, etBLOBSQL,    0,  0 },
  {  'W',  0, 2, etWIKISTR,    0,  0 },
  {  'h',  0, 4, etHTMLIZE,    0,  0 },
  {  'R',  0, 0, etROOT,       0,  0 },
  {  't',  0, 4, etHTTPIZE,    0,  0 },  /* "/" -> "%2F" */
  {  'T',  0, 4, etURLIZE,     0,  0 },  /* "/" unchanged */
  {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
  {  'F',  0, 4, etFOSSILIZE,  0,  0 },
  {  'S',  0, 4, etSTRINGID,   0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
  {  'o',  8, 0, etRADIX,      0,  2 },
  {  'u', 10, 0, etRADIX,      0,  0 },
  {  'x', 16, 0, etRADIX,      16, 1 },
  {  'X', 16, 0, etRADIX,      0,  4 },
659
660
661
662
663
664
665

666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
        }
        bufpt[j++] = '\'';
        length = j;
        assert( length==n+cnt+2 );
        break;
      }
      case etSQLESCAPE:

      case etSQLESCAPE2: {
        int i, j, n, ch, isnull;
        int needQuote;
        int limit = flag_alternateform ? va_arg(ap,int) : -1;

        char *escarg = va_arg(ap,char*);
        isnull = escarg==0;
        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
        if( limit<0 ) limit = strlen(escarg);
        for(i=n=0; i<limit; i++){
          if( escarg[i]=='\'' )  n++;
        }
        needQuote = !isnull && xtype==etSQLESCAPE2;
        n += i + 1 + needQuote*2;
        if( n>etBUFSIZE ){
          bufpt = zExtra = fossil_malloc( n );
        }else{
          bufpt = buf;
        }
        j = 0;
        if( needQuote ) bufpt[j++] = '\'';
        for(i=0; i<limit; i++){
          bufpt[j++] = ch = escarg[i];
          if( ch=='\'' ) bufpt[j++] = ch;
        }
        if( needQuote ) bufpt[j++] = '\'';
        bufpt[j] = 0;
        length = j;
        if( precision>=0 && precision<length ) length = precision;
        break;
      }
      case etHTMLIZE: {
        int limit = flag_alternateform ? va_arg(ap,int) : -1;







>
|



>





|









|


|

|







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
        }
        bufpt[j++] = '\'';
        length = j;
        assert( length==n+cnt+2 );
        break;
      }
      case etSQLESCAPE:
      case etSQLESCAPE2:
      case etSQLESCAPE3: {
        int i, j, n, ch, isnull;
        int needQuote;
        int limit = flag_alternateform ? va_arg(ap,int) : -1;
        char q = ((xtype==etSQLESCAPE3)?'"':'\'');  /* Quote characters */
        char *escarg = va_arg(ap,char*);
        isnull = escarg==0;
        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
        if( limit<0 ) limit = strlen(escarg);
        for(i=n=0; i<limit; i++){
          if( escarg[i]==q )  n++;
        }
        needQuote = !isnull && xtype==etSQLESCAPE2;
        n += i + 1 + needQuote*2;
        if( n>etBUFSIZE ){
          bufpt = zExtra = fossil_malloc( n );
        }else{
          bufpt = buf;
        }
        j = 0;
        if( needQuote ) bufpt[j++] = q;
        for(i=0; i<limit; i++){
          bufpt[j++] = ch = escarg[i];
          if( ch==q ) bufpt[j++] = ch;
        }
        if( needQuote ) bufpt[j++] = q;
        bufpt[j] = 0;
        length = j;
        if( precision>=0 && precision<length ) length = precision;
        break;
      }
      case etHTMLIZE: {
        int limit = flag_alternateform ? va_arg(ap,int) : -1;
Changes to src/rebuild.c.
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@    cols TEXT,               -- A color-key specification
@    sqlcode TEXT             -- An SQL SELECT statement for this report
@ );
;

static void rebuild_update_schema(void){
  int rc;
  db_multi_exec(zSchemaUpdates1);
  db_multi_exec(zSchemaUpdates2);

  rc = db_exists("SELECT 1 FROM sqlite_master"
                 " WHERE name='user' AND sql GLOB '* mtime *'");
  if( rc==0 ){
    db_multi_exec(
      "CREATE TEMP TABLE temp_user AS SELECT * FROM user;"
      "DROP TABLE user;"







|
|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@    cols TEXT,               -- A color-key specification
@    sqlcode TEXT             -- An SQL SELECT statement for this report
@ );
;

static void rebuild_update_schema(void){
  int rc;
  db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/);
  db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/);

  rc = db_exists("SELECT 1 FROM sqlite_master"
                 " WHERE name='user' AND sql GLOB '* mtime *'");
  if( rc==0 ){
    db_multi_exec(
      "CREATE TEMP TABLE temp_user AS SELECT * FROM user;"
      "DROP TABLE user;"
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  rc = db_exists("SELECT 1 FROM sqlite_master"
                 " WHERE name='reportfmt' AND sql GLOB '* mtime *'");
  if( rc==0 ){
    db_multi_exec(
      "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
      "DROP TABLE reportfmt;"
    );
    db_multi_exec(zSchemaUpdates2);
    db_multi_exec(
      "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
        " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
      "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
        " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
        "   FROM old_fmt;"
    );







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  rc = db_exists("SELECT 1 FROM sqlite_master"
                 " WHERE name='reportfmt' AND sql GLOB '* mtime *'");
  if( rc==0 ){
    db_multi_exec(
      "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
      "DROP TABLE reportfmt;"
    );
    db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/);
    db_multi_exec(
      "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
        " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
      "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
        " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
        "   FROM old_fmt;"
    );
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
    }
    if( zFNameFormat==0 ){
      /* We are doing "fossil rebuild" */
      manifest_crosslink(rid, pUse, MC_NONE);
    }else{
      /* We are doing "fossil deconstruct" */
      char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
      char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);

      blob_write_to_file(pUse,zFile);
      free(zFile);
      free(zUuid);
      blob_reset(pUse);
    }
    assert( blob_is_reset(pUse) );
    rebuild_step_done(rid);







|
>







252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
    }
    if( zFNameFormat==0 ){
      /* We are doing "fossil rebuild" */
      manifest_crosslink(rid, pUse, MC_NONE);
    }else{
      /* We are doing "fossil deconstruct" */
      char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
      char *zFile = mprintf(zFNameFormat /*works-like:"%s:%s"*/,
                            zUuid, zUuid+prefixLength);
      blob_write_to_file(pUse,zFile);
      free(zFile);
      free(zUuid);
      blob_reset(pUse);
    }
    assert( blob_is_reset(pUse) );
    rebuild_step_done(rid);
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
       " AND name NOT GLOB 'sqlite_*'"
       " AND name NOT GLOB 'fx_*'"
    );
    if( zTable==0 ) break;
    db_multi_exec("DROP TABLE %Q", zTable);
    free(zTable);
  }
  db_multi_exec(zRepositorySchema2);
  ticket_create_table(0);
  shun_artifacts();

  db_multi_exec(
     "INSERT INTO unclustered"
     " SELECT rid FROM blob EXCEPT SELECT rid FROM private"
  );







|







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
       " AND name NOT GLOB 'sqlite_*'"
       " AND name NOT GLOB 'fx_*'"
    );
    if( zTable==0 ) break;
    db_multi_exec("DROP TABLE %Q", zTable);
    free(zTable);
  }
  db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
  ticket_create_table(0);
  shun_artifacts();

  db_multi_exec(
     "INSERT INTO unclustered"
     " SELECT rid FROM blob EXCEPT SELECT rid FROM private"
  );
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
  verify_all_options();

  db_begin_transaction();
  ttyOutput = 1;
  errCnt = rebuild_db(randomizeFlag, 1, doClustering);
  reconstruct_private_table();
  db_multi_exec(
    "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());"
    "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());"
    "REPLACE INTO config(name,value,mtime) VALUES('rebuilt','%s',now());",
    CONTENT_SCHEMA, AUX_SCHEMA, get_version()
  );
  if( errCnt && !forceFlag ){
    fossil_print(
      "%d errors. Rolling back changes. Use --force to force a commit.\n",
      errCnt
    );







|
|
|







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
  verify_all_options();

  db_begin_transaction();
  ttyOutput = 1;
  errCnt = rebuild_db(randomizeFlag, 1, doClustering);
  reconstruct_private_table();
  db_multi_exec(
    "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
    "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
    "REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());",
    CONTENT_SCHEMA, AUX_SCHEMA, get_version()
  );
  if( errCnt && !forceFlag ){
    fossil_print(
      "%d errors. Rolling back changes. Use --force to force a commit.\n",
      errCnt
    );
Changes to src/report.c.
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    }
  }
  if( zOwner==0 ) zOwner = g.zLogin;
  style_submenu_element("Cancel", "Cancel", "reportlist");
  if( rn>0 ){
    style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
  }
  style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
  if( zErr ){
    @ <blockquote class="reportError">%h(zErr)</blockquote>
  }
  @ <form action="rptedit" method="post"><div>
  @ <input type="hidden" name="rn" value="%d(rn)" />
  @ <p>Report Title:<br />
  @ <input type="text" name="t" value="%h(zTitle)" size="60" /></p>







|







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    }
  }
  if( zOwner==0 ) zOwner = g.zLogin;
  style_submenu_element("Cancel", "Cancel", "reportlist");
  if( rn>0 ){
    style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
  }
  style_header("%s", rn>0 ? "Edit Report Format":"Create New Report Format");
  if( zErr ){
    @ <blockquote class="reportError">%h(zErr)</blockquote>
  }
  @ <form action="rptedit" method="post"><div>
  @ <input type="hidden" name="rn" value="%d(rn)" />
  @ <p>Report Title:<br />
  @ <input type="text" name="t" value="%h(zTitle)" size="60" /></p>
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
    if( g.perm.TktFmt ){
      style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn);
    }
    if( g.perm.NewTkt ){
      style_submenu_element("New Ticket", "Create a new ticket",
        "%s/tktnew", g.zTop);
    }
    style_header(zTitle);
    output_color_key(zClrKey, 1,
        "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
    @ <table border="1" cellpadding="2" cellspacing="0" class="report"
    @  id="reportTable">
    sState.rn = rn;
    sState.nCount = 0;
    report_restrict_sql(&zErr1);







|







1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
    if( g.perm.TktFmt ){
      style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn);
    }
    if( g.perm.NewTkt ){
      style_submenu_element("New Ticket", "Create a new ticket",
        "%s/tktnew", g.zTop);
    }
    style_header("%s", zTitle);
    output_color_key(zClrKey, 1,
        "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
    @ <table border="1" cellpadding="2" cellspacing="0" class="report"
    @  id="reportTable">
    sState.rn = rn;
    sState.nCount = 0;
    report_restrict_sql(&zErr1);
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134

/*
** show all reports, which can be used for ticket show.
** Output is written to stdout as tab delimited table
*/
void rpt_list_reports(void){
  Stmt q;
  const char aRptOutFrmt[] = "%s\t%s\n";

  fossil_print("Available reports:\n");
  fossil_print(aRptOutFrmt,"report number","report title");
  fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
  db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zRn = db_column_text(&q, 0);
    const char *zTitle = db_column_text(&q, 1);

    fossil_print(aRptOutFrmt,zRn,zTitle);
  }
  db_finalize(&q);
}

/*
** user defined separator used by ticket show command
*/







<
<

|
|





|







1110
1111
1112
1113
1114
1115
1116


1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

/*
** show all reports, which can be used for ticket show.
** Output is written to stdout as tab delimited table
*/
void rpt_list_reports(void){
  Stmt q;


  fossil_print("Available reports:\n");
  fossil_print("%s\t%s\n","report number","report title");
  fossil_print("%s\t%s\n",zFullTicketRptRn,zFullTicketRptTitle);
  db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zRn = db_column_text(&q, 0);
    const char *zTitle = db_column_text(&q, 1);

    fossil_print("%s\t%s\n",zRn,zTitle);
  }
  db_finalize(&q);
}

/*
** user defined separator used by ticket show command
*/
Changes to src/rss.c.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  blob_zero(&bSQL);
  blob_append( &bSQL, zSQL1, -1 );

  if( zType[0]!='a' ){
    if( zType[0]=='c' && !g.perm.Read ) zType = "x";
    if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
    if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
    blob_appendf(&bSQL, " AND event.type=%Q", zType);
  }else{
    if( !g.perm.Read ){
      if( g.perm.RdTkt && g.perm.RdWiki ){
        blob_append(&bSQL, " AND event.type!='ci'", -1);
      }else if( g.perm.RdTkt ){
        blob_append(&bSQL, " AND event.type=='t'", -1);
        







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  blob_zero(&bSQL);
  blob_append( &bSQL, zSQL1, -1 );

  if( zType[0]!='a' ){
    if( zType[0]=='c' && !g.perm.Read ) zType = "x";
    if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
    if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
    blob_append_sql(&bSQL, " AND event.type=%Q", zType);
  }else{
    if( !g.perm.Read ){
      if( g.perm.RdTkt && g.perm.RdWiki ){
        blob_append(&bSQL, " AND event.type!='ci'", -1);
      }else if( g.perm.RdTkt ){
        blob_append(&bSQL, " AND event.type=='t'", -1);
        
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
      nTagId = -1;
    }
  }else{
    nTagId = 0;
  }

  if( nTagId==-1 ){
    blob_appendf(&bSQL, " AND 0");
  }else if( nTagId!=0 ){
    blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
      " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
  }

  if( zFilename ){
    blob_appendf(&bSQL,
      " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
        zFilename, filename_collation()
    );
  }

  blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );








|

|




|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
      nTagId = -1;
    }
  }else{
    nTagId = 0;
  }

  if( nTagId==-1 ){
    blob_append_sql(&bSQL, " AND 0");
  }else if( nTagId!=0 ){
    blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
      " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
  }

  if( zFilename ){
    blob_append_sql(&bSQL,
      " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
        zFilename, filename_collation()
    );
  }

  blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  @   <channel>
  @     <title>%h(zProjectName)</title>
  @     <link>%s(g.zBaseURL)</link>
  @     <description>%h(zProjectDescr)</description>
  @     <pubDate>%s(zPubDate)</pubDate>
  @     <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
  free(zPubDate);
  db_prepare(&q, blob_str(&bSQL));
  blob_reset( &bSQL );
  while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
    const char *zId = db_column_text(&q, 1);
    const char *zCom = db_column_text(&q, 3);
    const char *zAuthor = db_column_text(&q, 4);
    char *zPrefix = "";
    char *zDate;







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  @   <channel>
  @     <title>%h(zProjectName)</title>
  @     <link>%s(g.zBaseURL)</link>
  @     <description>%h(zProjectDescr)</description>
  @     <pubDate>%s(zPubDate)</pubDate>
  @     <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
  free(zPubDate);
  db_prepare(&q, "%s", blob_sql_text(&bSQL));
  blob_reset( &bSQL );
  while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
    const char *zId = db_column_text(&q, 1);
    const char *zCom = db_column_text(&q, 3);
    const char *zAuthor = db_column_text(&q, 4);
    char *zPrefix = "";
    char *zDate;
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  /* We should be done with options.. */
    verify_all_options();

  blob_zero(&bSQL);
  blob_append( &bSQL, zSQL1, -1 );

  if( zType[0]!='a' ){
    blob_appendf(&bSQL, " AND event.type=%Q", zType);
  }

  if( zTicketUuid ){
    nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
      zTicketUuid);
    if ( nTagId==0 ){
      nTagId = -1;







|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  /* We should be done with options.. */
    verify_all_options();

  blob_zero(&bSQL);
  blob_append( &bSQL, zSQL1, -1 );

  if( zType[0]!='a' ){
    blob_append_sql(&bSQL, " AND event.type=%Q", zType);
  }

  if( zTicketUuid ){
    nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
      zTicketUuid);
    if ( nTagId==0 ){
      nTagId = -1;
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
      nTagId = -1;
    }
  }else{
    nTagId = 0;
  }

  if( nTagId==-1 ){
    blob_appendf(&bSQL, " AND 0");
  }else if( nTagId!=0 ){
    blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
      " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
  }

  if( zFilename ){
    blob_appendf(&bSQL,
      " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
        zFilename, filename_collation()
    );
  }

  blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );








|

|




|







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
      nTagId = -1;
    }
  }else{
    nTagId = 0;
  }

  if( nTagId==-1 ){
    blob_append_sql(&bSQL, " AND 0");
  }else if( nTagId!=0 ){
    blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
      " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
  }

  if( zFilename ){
    blob_append_sql(&bSQL,
      " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
        zFilename, filename_collation()
    );
  }

  blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  fossil_print("<title>%h</title>\n", zProjectName);
  fossil_print("<link>%s</link>\n", zBaseURL);
  fossil_print("<description>%h</description>\n", zProjectDescr);
  fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
  fossil_print("<generator>Fossil version %s %s</generator>\n",
               MANIFEST_VERSION, MANIFEST_DATE);
  free(zPubDate);
  db_prepare(&q, blob_str(&bSQL));
  blob_reset( &bSQL );
  while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
    const char *zId = db_column_text(&q, 1);
    const char *zCom = db_column_text(&q, 3);
    const char *zAuthor = db_column_text(&q, 4);
    char *zPrefix = "";
    char *zDate;







|







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  fossil_print("<title>%h</title>\n", zProjectName);
  fossil_print("<link>%s</link>\n", zBaseURL);
  fossil_print("<description>%h</description>\n", zProjectDescr);
  fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
  fossil_print("<generator>Fossil version %s %s</generator>\n",
               MANIFEST_VERSION, MANIFEST_DATE);
  free(zPubDate);
  db_prepare(&q, "%s", blob_sql_text(&bSQL));
  blob_reset( &bSQL );
  while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
    const char *zId = db_column_text(&q, 1);
    const char *zCom = db_column_text(&q, 3);
    const char *zAuthor = db_column_text(&q, 4);
    char *zPrefix = "";
    char *zDate;
Changes to src/search.c.
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
     timeline_utc()
  );
  iBest = db_int(0, "SELECT max(x) FROM srch");
  blob_append(&sql,
              "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
              "WHERE 1 ", -1);
  if(!fAll){
    blob_appendf(&sql,"AND x>%d ", iBest/3);
  }
  blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
  db_prepare(&q, blob_str(&sql));
  blob_reset(&sql);
  print_timeline(&q, nLimit, width, 0);
  db_finalize(&q);
}







|


|




229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
     timeline_utc()
  );
  iBest = db_int(0, "SELECT max(x) FROM srch");
  blob_append(&sql,
              "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
              "WHERE 1 ", -1);
  if(!fAll){
    blob_append_sql(&sql,"AND x>%d ", iBest/3);
  }
  blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
  db_prepare(&q, "%s", blob_sql_text(&sql));
  blob_reset(&sql);
  print_timeline(&q, nLimit, width, 0);
  db_finalize(&q);
}
Changes to src/setup.c.
17
18
19
20
21
22
23




24
25
26
27
28
29
30
**
** Implementation of the Setup page
*/
#include "config.h"
#include <assert.h>
#include "setup.h"





/*
** The table of web pages supported by this application is generated
** automatically by the "mkindex" program and written into a file
** named "page_index.h".  We include that file here to get access
** to the table.
*/
#include "page_index.h"







>
>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**
** Implementation of the Setup page
*/
#include "config.h"
#include <assert.h>
#include "setup.h"

#if INTERFACE
#define ArraySize(x) (sizeof(x)/sizeof(x[0]))
#endif

/*
** The table of web pages supported by this application is generated
** automatically by the "mkindex" program and written into a file
** named "page_index.h".  We include that file here to get access
** to the table.
*/
#include "page_index.h"
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

  style_header("Server Administration");

  /* Make sure the header contains <base href="...">.   Issue a warning
  ** if it does not. */
  if( !cgi_header_contains("<base href=") ){
    @ <p class="generalError"><b>Configuration Error:</b> Please add
    @ <tt>&lt;base href="$baseurl/$current_page"&gt;</tt> after
    @ <tt>&lt;head&gt;</tt> in the <a href="setup_header">HTML header</a>!</p>
  }

  @ <table border="0" cellspacing="7">
  setup_menu_entry("Users", "setup_ulist",
    "Grant privileges to individual users.");
  setup_menu_entry("Access", "setup_access",







|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

  style_header("Server Administration");

  /* Make sure the header contains <base href="...">.   Issue a warning
  ** if it does not. */
  if( !cgi_header_contains("<base href=") ){
    @ <p class="generalError"><b>Configuration Error:</b> Please add
    @ <tt>&lt;base href="$secureurl/$current_page"&gt;</tt> after
    @ <tt>&lt;head&gt;</tt> in the <a href="setup_header">HTML header</a>!</p>
  }

  @ <table border="0" cellspacing="7">
  setup_menu_entry("Users", "setup_ulist",
    "Grant privileges to individual users.");
  setup_menu_entry("Access", "setup_access",
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
  const char *zOldLogin;
  int doWrite;
  int uid, i;
  int higherUser = 0;  /* True if user being edited is SETUP and the */
                       /* user doing the editing is ADMIN.  Disallow editing */
  char *inherit[128];
  int a[128];
  char *oa[128];

  /* Must have ADMIN privileges to access this page
  */
  login_check_credentials();
  if( !g.perm.Admin ){ login_needed(); return; }

  /* Check to see if an ADMIN user is trying to edit a SETUP account.







|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  const char *zOldLogin;
  int doWrite;
  int uid, i;
  int higherUser = 0;  /* True if user being edited is SETUP and the */
                       /* user doing the editing is ADMIN.  Disallow editing */
  char *inherit[128];
  int a[128];
  const char *oa[128];

  /* Must have ADMIN privileges to access this page
  */
  login_check_credentials();
  if( !g.perm.Admin ){ login_needed(); return; }

  /* Check to see if an ADMIN user is trying to edit a SETUP account.
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
      @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
      style_footer();
      return;
    }
    login_verify_csrf_secret();
    db_multi_exec(
       "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
       "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s',now())",
      uid, P("login"), P("info"), zPw, zCap
    );
    if( atoi(PD("all","0"))>0 ){
      Blob sql;
      char *zErr = 0;
      blob_zero(&sql);
      if( zOldLogin==0 ){







|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
      @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
      style_footer();
      return;
    }
    login_verify_csrf_secret();
    db_multi_exec(
       "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
       "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
      uid, P("login"), P("info"), zPw, zCap
    );
    if( atoi(PD("all","0"))>0 ){
      Blob sql;
      char *zErr = 0;
      blob_zero(&sql);
      if( zOldLogin==0 ){
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493





































494
495
496
497
498
499
500
  /* figure out inherited permissions */
  memset(inherit, 0, sizeof(inherit));
  if( fossil_strcmp(zLogin, "developer") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
         "<span class=\"ueditInheritDeveloper\">&bull;</span>";
    }
    free(z2);
  }
  if( fossil_strcmp(zLogin, "reader") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
          "<span class=\"ueditInheritReader\">&bull;</span>";
    }
    free(z2);
  }
  if( fossil_strcmp(zLogin, "anonymous") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
           "<span class=\"ueditInheritAnonymous\">&bull;</span>";
    }
    free(z2);
  }
  if( fossil_strcmp(zLogin, "nobody") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
           "<span class=\"ueditInheritNobody\">&bull;</span>";
    }
    free(z2);
  }

  /* Begin generating the page
  */
  style_submenu_element("Cancel", "Cancel", "setup_ulist");
  if( uid ){
    style_header(mprintf("Edit User %h", zLogin));
  }else{
    style_header("Add A New User");
  }
  @ <div class="ueditCapBox">
  @ <form action="%s(g.zPath)" method="post"><div>
  login_insert_csrf_secret();
  if( login_is_special(zLogin) ){
    @ <input type="hidden" name="login" value="%s(zLogin)">
    @ <input type="hidden" name="info" value="">
    @ <input type="hidden" name="pw" value="*">
  }





































  @ <table>
  @ <tr>
  @   <td class="usetupEditLabel">User ID:</td>
  if( uid ){
    @   <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td>
  }else{
    @   <td>(new user)<input type="hidden" name="id" value="0" /></td>







|








|








|








|








|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
  /* figure out inherited permissions */
  memset(inherit, 0, sizeof(inherit));
  if( fossil_strcmp(zLogin, "developer") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
         "<span class=\"ueditInheritDeveloper\"><sub>[D]</sub></span>";
    }
    free(z2);
  }
  if( fossil_strcmp(zLogin, "reader") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
          "<span class=\"ueditInheritReader\"><sub>[R]</sub></span>";
    }
    free(z2);
  }
  if( fossil_strcmp(zLogin, "anonymous") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
           "<span class=\"ueditInheritAnonymous\"><sub>[A]</sub></span>";
    }
    free(z2);
  }
  if( fossil_strcmp(zLogin, "nobody") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
           "<span class=\"ueditInheritNobody\"><sub>[N]</sub></span>";
    }
    free(z2);
  }

  /* Begin generating the page
  */
  style_submenu_element("Cancel", "Cancel", "setup_ulist");
  if( uid ){
    style_header("Edit User %h", zLogin);
  }else{
    style_header("Add A New User");
  }
  @ <div class="ueditCapBox">
  @ <form action="%s(g.zPath)" method="post"><div>
  login_insert_csrf_secret();
  if( login_is_special(zLogin) ){
    @ <input type="hidden" name="login" value="%s(zLogin)">
    @ <input type="hidden" name="info" value="">
    @ <input type="hidden" name="pw" value="*">
  }
  @ <script type='text/javascript'>
  @ function updateCapabilityString(){
  @   /*
  @   ** This function updates the "#usetupEditCapability" span content
  @   ** with the capabilities selected by the interactive user, based
  @   ** upon the state of the capability checkboxes.
  @   */
  @   try {
  @     var inputs = document.getElementsByTagName('input');
  @     if( inputs && inputs.length ){
  @       var output = document.getElementById('usetupEditCapability');
  @       if( output ){
  @         var permsIds = [], x = 0;
  @         for(var i = 0; i < inputs.length; i++){
  @           var e = inputs[i];
  @           if( !e.name || !e.type ) continue;
  @           if( e.type.toLowerCase()!=='checkbox' ) continue;
  @           if( e.name.length===2 && e.name[0]==='a' ){
  @             // looks like a capability checkbox
  @             if( e.checked ){
  @               // grab the second character of the element
  @               // name, which is the textual flag for this
  @               // capability, and then add it to the result
  @               // array.
  @               permsIds[x++] = e.name[1];
  @             }
  @           }
  @         }
  @         permsIds.sort();
  @         output.innerHTML = permsIds.join('');
  @       }
  @     }
  @   } catch (e) {
  @     /* ignore errors */
  @   }
  @ }
  @ </script>
  @ <table>
  @ <tr>
  @   <td class="usetupEditLabel">User ID:</td>
  if( uid ){
    @   <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td>
  }else{
    @   <td>(new user)<input type="hidden" name="id" value="0" /></td>
514
515
516
517
518
519
520
521

522
523
524

525
526

527
528

529
530

531
532

533
534

535
536

537
538

539
540
541

542
543

544
545

546
547




548
549
550
551
552
553

554
555

556
557
558

559
560

561
562

563
564

565
566

567
568

569
570

571
572

573
574







575
576
577
578
579
580
581
  @ </tr>
  @ <tr>
  @   <td class="usetupEditLabel">Capabilities:</td>
  @   <td>
#define B(x) inherit[x]
  @ <table border=0><tr><td valign="top">
  if( g.perm.Setup ){
    @  <label><input type="checkbox" name="as"%s(oa['s']) />%s(B('s'))Setup

    @  </label><br />
  }
  @  <label><input type="checkbox" name="aa"%s(oa['a']) />%s(B('a'))Admin

  @  </label><br />
  @  <label><input type="checkbox" name="ad"%s(oa['d']) />%s(B('d'))Delete

  @  </label><br />
  @  <label><input type="checkbox" name="ae"%s(oa['e']) />%s(B('e'))Email

  @  </label><br />
  @  <label><input type="checkbox" name="ap"%s(oa['p']) />%s(B('p'))Password

  @  </label><br />
  @  <label><input type="checkbox" name="ai"%s(oa['i']) />%s(B('i'))Check-In

  @  </label><br />
  @  <label><input type="checkbox" name="ao"%s(oa['o']) />%s(B('o'))Check-Out

  @  </label><br />
  @  <label><input type="checkbox" name="ah"%s(oa['h']) />%s(B('h'))Hyperlinks

  @  </label><br />
  @  <label><input type="checkbox" name="ab"%s(oa['b']) />%s(B('b'))Attachments

  @  </label><br />
  @ </td><td><td width="40"></td><td valign="top">
  @  <label><input type="checkbox" name="au"%s(oa['u']) />%s(B('u'))Reader

  @  </label><br />
  @  <label><input type="checkbox" name="av"%s(oa['v']) />%s(B('v'))Developer

  @  </label><br />
  @  <label><input type="checkbox" name="ag"%s(oa['g']) />%s(B('g'))Clone

  @  </label><br />
  @  <label><input type="checkbox" name="aj"%s(oa['j']) />%s(B('j'))Read Wiki




  @  </label><br />
  @  <label><input type="checkbox" name="af"%s(oa['f']) />%s(B('f'))New Wiki
  @  </label><br />
  @  <label><input type="checkbox" name="am"%s(oa['m']) />%s(B('m'))Append Wiki
  @  </label><br />
  @  <label><input type="checkbox" name="ak"%s(oa['k']) />%s(B('k'))Write Wiki

  @  </label><br />
  @  <label><input type="checkbox" name="al"%s(oa['l']) />%s(B('l'))Moderate

  @  Wiki</label><br />
  @ </td><td><td width="40"></td><td valign="top">
  @  <label><input type="checkbox" name="ar"%s(oa['r']) />%s(B('r'))Read Ticket

  @  </label><br />
  @  <label><input type="checkbox" name="an"%s(oa['n']) />%s(B('n'))New Tickets

  @  </label><br />
  @  <label><input type="checkbox" name="ac"%s(oa['c']) />%s(B('c'))Append

  @  To Ticket </label><br />
  @  <label><input type="checkbox" name="aw"%s(oa['w']) />%s(B('w'))Write

  @  Tickets </label><br />
  @  <label><input type="checkbox" name="aq"%s(oa['q']) />%s(B('q'))Moderate

  @  Tickets </label><br />
  @  <label><input type="checkbox" name="at"%s(oa['t']) />%s(B('t'))Ticket

  @  Report </label><br />
  @  <label><input type="checkbox" name="ax"%s(oa['x']) />%s(B('x'))Private

  @  </label><br />
  @  <label><input type="checkbox" name="az"%s(oa['z']) />%s(B('z'))Download

  @  Zip </label>
  @ </td></tr></table>







  @   </td>
  @ </tr>
  if( !login_is_special(zLogin) ){
    @ <tr>
    @   <td align="right">Password:</td>
    if( zPw[0] ){
      /* Obscure the password for all users */







|
>
|

|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|

|
>
|
|
>
|
|
>
|
|
>
>
>
>
|
|
|
<
|
|
>
|
|
>
|

|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
>
>
>
>
>
>







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
  @ </tr>
  @ <tr>
  @   <td class="usetupEditLabel">Capabilities:</td>
  @   <td>
#define B(x) inherit[x]
  @ <table border=0><tr><td valign="top">
  if( g.perm.Setup ){
    @  <label><input type="checkbox" name="as"%s(oa['s'])
    @                onchange="updateCapabilityString()"/>
    @  Setup%s(B('s'))</label><br />
  }
  @  <label><input type="checkbox" name="aa"%s(oa['a'])
  @                onchange="updateCapabilityString()" />
  @  Admin%s(B('a'))</label><br />
  @  <label><input type="checkbox" name="ad"%s(oa['d'])
  @                onchange="updateCapabilityString()" />
  @  Delete%s(B('d'))</label><br />
  @  <label><input type="checkbox" name="ae"%s(oa['e'])
  @                onchange="updateCapabilityString()" />
  @  Email%s(B('e'))</label><br />
  @  <label><input type="checkbox" name="ap"%s(oa['p'])
  @                onchange="updateCapabilityString()" />
  @  Password%s(B('p'))</label><br />
  @  <label><input type="checkbox" name="ai"%s(oa['i'])
  @                onchange="updateCapabilityString()" />
  @  Check-In%s(B('i'))</label><br />
  @  <label><input type="checkbox" name="ao"%s(oa['o'])
  @                onchange="updateCapabilityString()" />
  @  Check-Out%s(B('o'))</label><br />
  @  <label><input type="checkbox" name="ah"%s(oa['h'])
  @                onchange="updateCapabilityString()" />
  @  Hyperlinks%s(B('h'))</label><br />
  @  <label><input type="checkbox" name="ab"%s(oa['b'])
  @                onchange="updateCapabilityString()" />
  @  Attachments%s(B('b'))</label><br />
  @ </td><td><td width="40"></td><td valign="top">
  @  <label><input type="checkbox" name="au"%s(oa['u'])
  @                onchange="updateCapabilityString()" />
  @  Reader%s(B('u'))</label><br />
  @  <label><input type="checkbox" name="av"%s(oa['v'])
  @                onchange="updateCapabilityString()" />
  @  Developer%s(B('v'))</label><br />
  @  <label><input type="checkbox" name="ag"%s(oa['g'])
  @                onchange="updateCapabilityString()" />
  @  Clone%s(B('g'))</label><br />
  @  <label><input type="checkbox" name="aj"%s(oa['j'])
  @                onchange="updateCapabilityString()" />
  @  Read Wiki%s(B('j'))</label><br />
  @  <label><input type="checkbox" name="af"%s(oa['f'])
  @                onchange="updateCapabilityString()" />
  @  New Wiki%s(B('f'))</label><br />
  @  <label><input type="checkbox" name="am"%s(oa['m'])
  @                onchange="updateCapabilityString()" />

  @  Append Wiki%s(B('m'))</label><br />
  @  <label><input type="checkbox" name="ak"%s(oa['k'])
  @                onchange="updateCapabilityString()" />
  @  Write Wiki%s(B('k'))</label><br />
  @  <label><input type="checkbox" name="al"%s(oa['l'])
  @                onchange="updateCapabilityString()" />
  @  Moderate Wiki%s(B('l'))</label><br />
  @ </td><td><td width="40"></td><td valign="top">
  @  <label><input type="checkbox" name="ar"%s(oa['r'])
  @                onchange="updateCapabilityString()" />
  @  Read Ticket%s(B('r'))</label><br />
  @  <label><input type="checkbox" name="an"%s(oa['n'])
  @                onchange="updateCapabilityString()" />
  @  New Tickets%s(B('n'))</label><br />
  @  <label><input type="checkbox" name="ac"%s(oa['c'])
  @                onchange="updateCapabilityString()" />
  @  Append To Ticket%s(B('c'))</label><br />
  @  <label><input type="checkbox" name="aw"%s(oa['w'])
  @                onchange="updateCapabilityString()" />
  @  Write Tickets%s(B('w'))</label><br />
  @  <label><input type="checkbox" name="aq"%s(oa['q'])
  @                onchange="updateCapabilityString()" />
  @  Moderate Tickets%s(B('q'))</label><br />
  @  <label><input type="checkbox" name="at"%s(oa['t'])
  @                onchange="updateCapabilityString()" />
  @  Ticket Report%s(B('t'))</label><br />
  @  <label><input type="checkbox" name="ax"%s(oa['x'])
  @                onchange="updateCapabilityString()" />
  @  Private%s(B('x'))</label><br />
  @  <label><input type="checkbox" name="az"%s(oa['z'])
  @                onchange="updateCapabilityString()" />
  @  Download Zip%s(B('z'))</label>
  @ </td></tr>
  @ </table>
  @   </td>
  @ </tr>
  @ <tr>
  @   <td class="usetupEditLabel">Selected Cap.:</td>
  @   <td>
  @     <span id="usetupEditCapability">(missing JS?)</span>
  @   </td>
  @ </tr>
  if( !login_is_special(zLogin) ){
    @ <tr>
    @   <td align="right">Password:</td>
    if( zPw[0] ){
      /* Obscure the password for all users */
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
    @   <td>&nbsp;</td>
    @   <td><input type="submit" name="submit" value="Apply Changes" /></td>
    @ </tr>
  }
  @ </table>
  @ </div></form>
  @ </div>

  @ <h2>Privileges And Capabilities:</h2>
  @ <ul>
  if( higherUser ){
    @ <li><p class="missingPriv">
    @ User %h(zLogin) has Setup privileges and you only have Admin privileges
    @ so you are not permitted to make changes to %h(zLogin).
    @ </p></li>
    @
  }
  @ <li><p>
  @ The <span class="capability">Setup</span> user can make arbitrary
  @ configuration changes. An <span class="usertype">Admin</span> user
  @ can add other users and change user privileges
  @ and reset user passwords.  Both automatically get all other privileges
  @ listed below.  Use these two settings with discretion.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritNobody"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">nobody</span> that
  @ are available to all users regardless of whether or not they are logged in.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritAnonymous"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">anonymous</span> that
  @ are inherited by all logged-in users.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritDeveloper"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">developer</span> that
  @ are inherited by all users with the
  @ <span class="capability">Developer</span> privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritReader"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">reader</span> that
  @ are inherited by all users with the <span class="capability">Reader</span>
  @ privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Delete</span> privilege give the user the







>


















|





|





|






|







675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
    @   <td>&nbsp;</td>
    @   <td><input type="submit" name="submit" value="Apply Changes" /></td>
    @ </tr>
  }
  @ </table>
  @ </div></form>
  @ </div>
  @ <script type='text/javascript'>updateCapabilityString();</script>
  @ <h2>Privileges And Capabilities:</h2>
  @ <ul>
  if( higherUser ){
    @ <li><p class="missingPriv">
    @ User %h(zLogin) has Setup privileges and you only have Admin privileges
    @ so you are not permitted to make changes to %h(zLogin).
    @ </p></li>
    @
  }
  @ <li><p>
  @ The <span class="capability">Setup</span> user can make arbitrary
  @ configuration changes. An <span class="usertype">Admin</span> user
  @ can add other users and change user privileges
  @ and reset user passwords.  Both automatically get all other privileges
  @ listed below.  Use these two settings with discretion.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritNobody"><sub>N</sub></span>" subscript suffix
  @ indicates the privileges of <span class="usertype">nobody</span> that
  @ are available to all users regardless of whether or not they are logged in.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritAnonymous"><sub>A</sub></span>" subscript suffix
  @ indicates the privileges of <span class="usertype">anonymous</span> that
  @ are inherited by all logged-in users.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritDeveloper"><sub>D</sub></span>" subscript suffix
  @ indicates the privileges of <span class="usertype">developer</span> that
  @ are inherited by all users with the
  @ <span class="capability">Developer</span> privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritReader"><sub>R</sub></span>" subscript suffix
  @ indicates the privileges of <span class="usertype">reader</span> that
  @ are inherited by all users with the <span class="capability">Reader</span>
  @ privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Delete</span> privilege give the user the
897
898
899
900
901
902
903








904
905
906
907
908
909
910
  }

  style_header("Access Control Settings");
  db_begin_transaction();
  @ <form action="%s(g.zTop)/setup_access" method="post"><div>
  login_insert_csrf_secret();
  @ <hr />








  onoff_attribute("Require password for local access",
     "localauth", "localauth", 0, 0);
  @ <p>When enabled, the password sign-in is always required for
  @ web access.  When disabled, unrestricted web access from 127.0.0.1
  @ is allowed for the <a href="%s(g.zTop)/help/ui">fossil ui</a> command or
  @ from the <a href="%s(g.zTop)/help/server">fossil server</a>,
  @ <a href="%s(g.zTop)/help/http">fossil http</a> commands when the







>
>
>
>
>
>
>
>







971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
  }

  style_header("Access Control Settings");
  db_begin_transaction();
  @ <form action="%s(g.zTop)/setup_access" method="post"><div>
  login_insert_csrf_secret();
  @ <hr />
  onoff_attribute("Redirect to HTTPS on the Login page",
     "redirect-to-https", "redirhttps", 0, 0);
  @ <p>When selected, force the use of HTTPS for the Login page.
  @ <p>Details:  When enabled, this option causes the $secureurl TH1 
  @ variable is set to an "https:" variant of $baseurl.  Otherwise,
  @ $secureurl is just an alias for $baseurl.  Also when enabled, the
  @ Login page redirects to https if accessed via http.
  @ <hr />
  onoff_attribute("Require password for local access",
     "localauth", "localauth", 0, 0);
  @ <p>When enabled, the password sign-in is always required for
  @ web access.  When disabled, unrestricted web access from 127.0.0.1
  @ is allowed for the <a href="%s(g.zTop)/help/ui">fossil ui</a> command or
  @ from the <a href="%s(g.zTop)/help/server">fossil server</a>,
  @ <a href="%s(g.zTop)/help/http">fossil http</a> commands when the
1003
1004
1005
1006
1007
1008
1009




1010
1011
1012
1013
1014
1015
1016
  @ if it does, your server will end up computing diffs and annotations for
  @ every historical version of every file and creating ZIPs and tarballs of
  @ every historical check-in, which can use a lot of CPU and bandwidth
  @ even for relatively small projects.</p>
  @
  @ <p>Additional parameters that control this behavior:</p>
  @ <blockquote>




  onoff_attribute("Require mouse movement before enabling hyperlinks",
                  "auto-hyperlink-mouseover", "ahmo", 0, 0);
  @ <br>
  entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5,
                  "auto-hyperlink-delay", "ah-delay", "10", 0);
  @ </blockquote>
  @ <p>Hyperlinks for user "nobody" are normally enabled as soon as the page







>
>
>
>







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
  @ if it does, your server will end up computing diffs and annotations for
  @ every historical version of every file and creating ZIPs and tarballs of
  @ every historical check-in, which can use a lot of CPU and bandwidth
  @ even for relatively small projects.</p>
  @
  @ <p>Additional parameters that control this behavior:</p>
  @ <blockquote>
  onoff_attribute("Enable hyperlinks for humans (as deduced from the UserAgent "
                  " HTTP header string)",
                  "auto-hyperlink-ishuman", "ahis", 0, 0);
  @ <br>
  onoff_attribute("Require mouse movement before enabling hyperlinks",
                  "auto-hyperlink-mouseover", "ahmo", 0, 0);
  @ <br>
  entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5,
                  "auto-hyperlink-delay", "ah-delay", "10", 0);
  @ </blockquote>
  @ <p>Hyperlinks for user "nobody" are normally enabled as soon as the page
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
  const char *zNewName = PD("newname", "New Login Group");

  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }
  file_canonical_name(g.zRepositoryName, &fullName, 0);
  zSelfRepo = mprintf(blob_str(&fullName));
  blob_reset(&fullName);
  if( P("join")!=0 ){
    login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
  }else if( P("leave") ){
    login_group_leave(&zErrMsg);
  }
  style_header("Login Group Configuration");







|







1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
  const char *zNewName = PD("newname", "New Login Group");

  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }
  file_canonical_name(g.zRepositoryName, &fullName, 0);
  zSelfRepo = fossil_strdup(blob_str(&fullName));
  blob_reset(&fullName);
  if( P("join")!=0 ){
    login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
  }else if( P("leave") ){
    login_group_leave(&zErrMsg);
  }
  style_header("Login Group Configuration");
1172
1173
1174
1175
1176
1177
1178
1179

1180
1181
1182
1183
1184
1185
1186
void setup_timeline(void){
  double tmDiff;
  char zTmDiff[20];
  static const char *const azTimeFormats[] = {
      "0", "HH:MM",
      "1", "HH:MM:SS",
      "2", "YYYY-MM-DD HH:MM",
      "3", "YYMMDD HH:MM"

  };
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }

  style_header("Timeline Display Preferences");







|
>







1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
void setup_timeline(void){
  double tmDiff;
  char zTmDiff[20];
  static const char *const azTimeFormats[] = {
      "0", "HH:MM",
      "1", "HH:MM:SS",
      "2", "YYYY-MM-DD HH:MM",
      "3", "YYMMDD HH:MM",
      "4", "(off)"
  };
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }

  style_header("Timeline Display Preferences");
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
    sqlite3_snprintf(sizeof(zTmDiff), zTmDiff, "%.1f", -tmDiff);
    @ %s(zTmDiff) hours behind UTC.</p>
  }else{
    @ %s(zTmDiff) hours ahead of UTC.</p>
  }

  @ <hr />
  multiple_choice_attribute("Per-Item Time Format", "timeline-date-format", "tdf", "0",
                            4, azTimeFormats);
  @ <p>If the "HH:MM" or "HH:MM:SS" format is selected, then the date is shown
  @ in a separate box (using CSS class "timelineDate") whenever the date changes.
  @ With the "YYYY-MM-DD&nbsp;HH:MM" and "YYMMDD ..." formats, the complete date
  @ and time is shown on every timeline entry (using the CSS class "timelineTime").</p>

  @ <hr />
  onoff_attribute("Show version differences by default",







|
|







1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
    sqlite3_snprintf(sizeof(zTmDiff), zTmDiff, "%.1f", -tmDiff);
    @ %s(zTmDiff) hours behind UTC.</p>
  }else{
    @ %s(zTmDiff) hours ahead of UTC.</p>
  }

  @ <hr />
  multiple_choice_attribute("Per-Item Time Format", "timeline-date-format",
            "tdf", "0", ArraySize(azTimeFormats)/2, azTimeFormats);
  @ <p>If the "HH:MM" or "HH:MM:SS" format is selected, then the date is shown
  @ in a separate box (using CSS class "timelineDate") whenever the date changes.
  @ With the "YYYY-MM-DD&nbsp;HH:MM" and "YYMMDD ..." formats, the complete date
  @ and time is shown on every timeline entry (using the CSS class "timelineTime").</p>

  @ <hr />
  onoff_attribute("Show version differences by default",
1259
1260
1261
1262
1263
1264
1265



1266

1267
1268
1269
1270
1271
1272
1273
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }

  (void) aCmdHelp; /* NOTE: Silence compiler warning. */
  style_header("Settings");



  db_open_local(0);

  db_begin_transaction();
  @ <p>This page provides a simple interface to the "fossil setting" command.
  @ See the "fossil help setting" output below for further information on
  @ the meaning of each setting.</p><hr />
  @ <form action="%s(g.zTop)/setup_settings" method="post"><div>
  @ <table border="0"><tr><td valign="top">
  login_insert_csrf_secret();







>
>
>
|
>







1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }

  (void) aCmdHelp; /* NOTE: Silence compiler warning. */
  style_header("Settings");
  if(!g.repositoryOpen){
    /* Provide read-only access to versioned settings,
       but only if no repo file was explicitly provided. */
    db_open_local(0);
  }
  db_begin_transaction();
  @ <p>This page provides a simple interface to the "fossil setting" command.
  @ See the "fossil help setting" output below for further information on
  @ the meaning of each setting.</p><hr />
  @ <form action="%s(g.zTop)/setup_settings" method="post"><div>
  @ <table border="0"><tr><td valign="top">
  login_insert_csrf_secret();
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
  }else if( P("fixbase")!=0 ){
    const char *z = db_get("header", (char*)zDefaultHeader);
    char *zHead = strstr(z, "<head>");
    if( strstr(z, "<base href=")==0 && zHead!=0 ){
      char *zNew;
      char *zTail = &zHead[6];
      while( fossil_isspace(zTail[0]) ) zTail++;
      zNew = mprintf("%.*s\n<base href=\"$baseurl/$current_page\" />\n%s",
                     zHead+6-z, z, zTail);
      cgi_replace_parameter("header", zNew);
      db_set("header", zNew, 0);
    }
  }

  style_header("Edit Page Header");
  @ <form action="%R/setup_header" method="post"><div>

  /* Make sure the header contains <base href="...">.   Issue a warning
  ** if it does not. */
  if( !cgi_header_contains("<base href=") ){
    @ <p class="generalError">Please add
    @ <tt>&lt;base href="$baseurl/$current_page"&gt;</tt> after
    @ <tt>&lt;head&gt;</tt> in the header!
    @ <input type="submit" name="fixbase" value="Add &lt;base&gt; Now"></p>
  }

  login_insert_csrf_secret();
  @ <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







|













|







1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
  }else if( P("fixbase")!=0 ){
    const char *z = db_get("header", (char*)zDefaultHeader);
    char *zHead = strstr(z, "<head>");
    if( strstr(z, "<base href=")==0 && zHead!=0 ){
      char *zNew;
      char *zTail = &zHead[6];
      while( fossil_isspace(zTail[0]) ) zTail++;
      zNew = mprintf("%.*s\n<base href=\"$secureurl/$current_page\" />\n%s",
                     zHead+6-z, z, zTail);
      cgi_replace_parameter("header", zNew);
      db_set("header", zNew, 0);
    }
  }

  style_header("Edit Page Header");
  @ <form action="%R/setup_header" method="post"><div>

  /* Make sure the header contains <base href="...">.   Issue a warning
  ** if it does not. */
  if( !cgi_header_contains("<base href=") ){
    @ <p class="generalError">Please add
    @ <tt>&lt;base href="$secureurl/$current_page"&gt;</tt> after
    @ <tt>&lt;head&gt;</tt> in the header!
    @ <input type="submit" name="fixbase" value="Add &lt;base&gt; Now"></p>
  }

  login_insert_csrf_secret();
  @ <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
Changes to src/shell.c.
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#include <windows.h>

/* Saved resource information for the beginning of an operation */
static HANDLE hProcess;
static FILETIME ftKernelBegin;
static FILETIME ftUserBegin;
static sqlite3_int64 ftWallBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);

static GETPROCTIMES getProcessTimesAddr = NULL;

/*
** Check to see if we have timer support.  Return 1 if necessary
** support found (or found previously).
*/
static int hasTimer(void){
  if( getProcessTimesAddr ){
    return 1;
  } else {
    /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
    ** See if the version we are running on has it, and if it does, save off
    ** a pointer to it and the current process handle.
    */
    hProcess = GetCurrentProcess();
    if( hProcess ){
      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
      if( NULL != hinstLib ){

        getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
        if( NULL != getProcessTimesAddr ){
          return 1;
        }
        FreeLibrary(hinstLib); 
      }
    }
  }
  return 0;
}

/*
** Begin timing an operation
*/
static void beginTimer(void){
  if( enableTimer && getProcessTimesAddr ){
    FILETIME ftCreation, ftExit;
    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);

    ftWallBegin = timeOfDay();
  }
}

/* Return the difference of two FILETIME structs in seconds */
static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
  return (double) ((i64End - i64Start) / 10000000.0);
}

/*
** Print the timing results.
*/
static void endTimer(void){
  if( enableTimer && getProcessTimesAddr){
    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
    sqlite3_int64 ftWallEnd = timeOfDay();
    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
    printf("Run Time: real %.3f user %f sys %f\n",
       (ftWallEnd - ftWallBegin)*0.001,
       timeDiff(&ftUserBegin, &ftUserEnd),
       timeDiff(&ftKernelBegin, &ftKernelEnd));
  }
}








|
>










|
|
|





>
|
















|
>


















|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#include <windows.h>

/* Saved resource information for the beginning of an operation */
static HANDLE hProcess;
static FILETIME ftKernelBegin;
static FILETIME ftUserBegin;
static sqlite3_int64 ftWallBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
                                    LPFILETIME, LPFILETIME);
static GETPROCTIMES getProcessTimesAddr = NULL;

/*
** Check to see if we have timer support.  Return 1 if necessary
** support found (or found previously).
*/
static int hasTimer(void){
  if( getProcessTimesAddr ){
    return 1;
  } else {
    /* GetProcessTimes() isn't supported in WIN95 and some other Windows
    ** versions. See if the version we are running on has it, and if it
    ** does, save off a pointer to it and the current process handle.
    */
    hProcess = GetCurrentProcess();
    if( hProcess ){
      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
      if( NULL != hinstLib ){
        getProcessTimesAddr =
            (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
        if( NULL != getProcessTimesAddr ){
          return 1;
        }
        FreeLibrary(hinstLib); 
      }
    }
  }
  return 0;
}

/*
** Begin timing an operation
*/
static void beginTimer(void){
  if( enableTimer && getProcessTimesAddr ){
    FILETIME ftCreation, ftExit;
    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
                        &ftKernelBegin,&ftUserBegin);
    ftWallBegin = timeOfDay();
  }
}

/* Return the difference of two FILETIME structs in seconds */
static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
  return (double) ((i64End - i64Start) / 10000000.0);
}

/*
** Print the timing results.
*/
static void endTimer(void){
  if( enableTimer && getProcessTimesAddr){
    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
    sqlite3_int64 ftWallEnd = timeOfDay();
    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
    printf("Run Time: real %.3f user %f sys %f\n",
       (ftWallEnd - ftWallBegin)*0.001,
       timeDiff(&ftUserBegin, &ftUserEnd),
       timeDiff(&ftKernelBegin, &ftKernelEnd));
  }
}

453
454
455
456
457
458
459

460
461
462
463
464
465
466
*/
typedef struct ShellState ShellState;
struct ShellState {
  sqlite3 *db;           /* The database */
  int echoOn;            /* True to echo input commands */
  int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
  int statsOn;           /* True to display memory stats before each finalize */

  int outCount;          /* Revert to stdout when reaching zero */
  int cnt;               /* Number of records displayed so far */
  FILE *out;             /* Write results here */
  FILE *traceOut;        /* Output for sqlite3_trace() */
  int nErr;              /* Number of errors seen */
  int mode;              /* An output mode setting */
  int writableSchema;    /* True if PRAGMA writable_schema=ON */







>







456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
*/
typedef struct ShellState ShellState;
struct ShellState {
  sqlite3 *db;           /* The database */
  int echoOn;            /* True to echo input commands */
  int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
  int statsOn;           /* True to display memory stats before each finalize */
  int scanstatsOn;       /* True to display scan stats before each finalize */
  int outCount;          /* Revert to stdout when reaching zero */
  int cnt;               /* Number of records displayed so far */
  FILE *out;             /* Write results here */
  FILE *traceOut;        /* Output for sqlite3_trace() */
  int nErr;              /* Number of errors seen */
  int mode;              /* An output mode setting */
  int writableSchema;    /* True if PRAGMA writable_schema=ON */
721
722
723
724
725
726
727
728






729
730
731
732
733
734
735
}
#endif

/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){






  int i;
  ShellState *p = (ShellState*)pArg;

  switch( p->mode ){
    case MODE_Line: {
      int w = 5;
      if( azArg==0 ) break;







|
>
>
>
>
>
>







725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
}
#endif

/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
  void *pArg,
  int nArg,        /* Number of result columns */
  char **azArg,    /* Text of each result column */
  char **azCol,    /* Column names */
  int *aiType      /* Column types */
){
  int i;
  ShellState *p = (ShellState*)pArg;

  switch( p->mode ){
    case MODE_Line: {
      int w = 5;
      if( azArg==0 ) break;
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
#endif
      if( p->cnt++==0 && p->showHeader ){
        for(i=0; i<nArg; i++){
          output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
        }
        fprintf(p->out,"%s",p->newline);
      }
      if( azArg>0 ){
        for(i=0; i<nArg; i++){
          output_csv(p, azArg[i], i<nArg-1);
        }
        fprintf(p->out,"%s",p->newline);
      }
#if defined(WIN32) || defined(_WIN32)
      fflush(p->out);







|







888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
#endif
      if( p->cnt++==0 && p->showHeader ){
        for(i=0; i<nArg; i++){
          output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
        }
        fprintf(p->out,"%s",p->newline);
      }
      if( nArg>0 ){
        for(i=0; i<nArg; i++){
          output_csv(p, azArg[i], i<nArg-1);
        }
        fprintf(p->out,"%s",p->newline);
      }
#if defined(WIN32) || defined(_WIN32)
      fflush(p->out);
1100
1101
1102
1103
1104
1105
1106

1107

1108
1109
1110

1111
1112
1113

1114

1115
1116
1117

1118

1119
1120
1121
1122

1123
1124
1125

1126

1127
1128
1129

1130
1131
1132

1133
1134
1135

1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146

1147

1148

1149
1150

1151
1152

1153
1154
1155
1156
1157

1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186













































1187
1188
1189
1190
1191
1192
1193
  int iCur;
  int iHiwtr;

  if( pArg && pArg->out ){
    
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);

    fprintf(pArg->out, "Memory Used:                         %d (max %d) bytes\n", iCur, iHiwtr);

    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Number of Outstanding Allocations:   %d (max %d)\n", iCur, iHiwtr);

    if( pArg->shellFlgs & SHFLG_Pagecache ){
      iHiwtr = iCur = -1;
      sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);

      fprintf(pArg->out, "Number of Pcache Pages Used:         %d (max %d) pages\n", iCur, iHiwtr);

    }
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);

    fprintf(pArg->out, "Number of Pcache Overflow Bytes:     %d (max %d) bytes\n", iCur, iHiwtr);

    if( pArg->shellFlgs & SHFLG_Scratch ){
      iHiwtr = iCur = -1;
      sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
      fprintf(pArg->out, "Number of Scratch Allocations Used:  %d (max %d)\n", iCur, iHiwtr);

    }
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);

    fprintf(pArg->out, "Number of Scratch Overflow Bytes:    %d (max %d) bytes\n", iCur, iHiwtr);

    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Largest Allocation:                  %d bytes\n", iHiwtr);

    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Largest Pcache Allocation:           %d bytes\n", iHiwtr);

    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Largest Scratch Allocation:          %d bytes\n", iHiwtr);

#ifdef YYTRACKMAXSTACKDEPTH
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Deepest Parser Stack:                %d (max %d)\n", iCur, iHiwtr);

#endif
  }

  if( pArg && pArg->out && db ){
    if( pArg->shellFlgs & SHFLG_Lookaside ){
      iHiwtr = iCur = -1;
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);

      fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n", iCur, iHiwtr);

      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);

      fprintf(pArg->out, "Successful lookaside attempts:       %d\n", iHiwtr);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);

      fprintf(pArg->out, "Lookaside failures due to size:      %d\n", iHiwtr);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);

      fprintf(pArg->out, "Lookaside failures due to OOM:       %d\n", iHiwtr);
    }
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Pager Heap Usage:                    %d bytes\n", iCur);    iHiwtr = iCur = -1;

    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
    fprintf(pArg->out, "Page cache hits:                     %d\n", iCur);
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
    fprintf(pArg->out, "Page cache misses:                   %d\n", iCur); 
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
    fprintf(pArg->out, "Page cache writes:                   %d\n", iCur); 
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur); 
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n", iCur); 
  }

  if( pArg && pArg->out && db && pArg->pStmt ){
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);

    fprintf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
    fprintf(pArg->out, "Sort Operations:                     %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
    fprintf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
    fprintf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
  }

  return 0;
}














































/*
** Parameter azArray points to a zero-terminated array of strings. zStr
** points to a single nul-terminated string. Return non-zero if zStr
** is equal, according to strcmp(), to any of the strings in the array.
** Otherwise, return zero.
*/







>
|
>


|
>



>
|
>



>
|
>



|
>



>
|
>


|
>


|
>


|
>



|
>






|
>
|
>
|
>

|
>

|
>




|
>










|


|



|
>



|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
  int iCur;
  int iHiwtr;

  if( pArg && pArg->out ){
    
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out,
            "Memory Used:                         %d (max %d) bytes\n",
            iCur, iHiwtr);
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Number of Outstanding Allocations:   %d (max %d)\n",
            iCur, iHiwtr);
    if( pArg->shellFlgs & SHFLG_Pagecache ){
      iHiwtr = iCur = -1;
      sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
      fprintf(pArg->out,
              "Number of Pcache Pages Used:         %d (max %d) pages\n",
              iCur, iHiwtr);
    }
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out,
            "Number of Pcache Overflow Bytes:     %d (max %d) bytes\n",
            iCur, iHiwtr);
    if( pArg->shellFlgs & SHFLG_Scratch ){
      iHiwtr = iCur = -1;
      sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
      fprintf(pArg->out, "Number of Scratch Allocations Used:  %d (max %d)\n",
              iCur, iHiwtr);
    }
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out,
            "Number of Scratch Overflow Bytes:    %d (max %d) bytes\n",
            iCur, iHiwtr);
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Largest Allocation:                  %d bytes\n",
            iHiwtr);
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Largest Pcache Allocation:           %d bytes\n",
            iHiwtr);
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Largest Scratch Allocation:          %d bytes\n",
            iHiwtr);
#ifdef YYTRACKMAXSTACKDEPTH
    iHiwtr = iCur = -1;
    sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Deepest Parser Stack:                %d (max %d)\n",
            iCur, iHiwtr);
#endif
  }

  if( pArg && pArg->out && db ){
    if( pArg->shellFlgs & SHFLG_Lookaside ){
      iHiwtr = iCur = -1;
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
                        &iCur, &iHiwtr, bReset);
      fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n",
              iCur, iHiwtr);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
                        &iCur, &iHiwtr, bReset);
      fprintf(pArg->out, "Successful lookaside attempts:       %d\n", iHiwtr);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
                        &iCur, &iHiwtr, bReset);
      fprintf(pArg->out, "Lookaside failures due to size:      %d\n", iHiwtr);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
                        &iCur, &iHiwtr, bReset);
      fprintf(pArg->out, "Lookaside failures due to OOM:       %d\n", iHiwtr);
    }
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Pager Heap Usage:                    %d bytes\n",iCur);
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
    fprintf(pArg->out, "Page cache hits:                     %d\n", iCur);
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
    fprintf(pArg->out, "Page cache misses:                   %d\n", iCur); 
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
    fprintf(pArg->out, "Page cache writes:                   %d\n", iCur); 
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n",iCur); 
    iHiwtr = iCur = -1;
    sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n",iCur); 
  }

  if( pArg && pArg->out && db && pArg->pStmt ){
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
                               bReset);
    fprintf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
    fprintf(pArg->out, "Sort Operations:                     %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
    fprintf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
    fprintf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
  }

  return 0;
}

/*
** Display scan stats.
*/
static void display_scanstats(
  sqlite3 *db,                    /* Database to query */
  ShellState *pArg                /* Pointer to ShellState */
){
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  int i, k, n, mx;
  fprintf(pArg->out, "-------- scanstats --------\n");
  mx = 0;
  for(k=0; k<=mx; k++){
    double rEstLoop = 1.0;
    for(i=n=0; 1; i++){
      sqlite3_stmt *p = pArg->pStmt;
      sqlite3_int64 nLoop, nVisit;
      double rEst;
      int iSid;
      const char *zExplain;
      if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
        break;
      }
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
      if( iSid>mx ) mx = iSid;
      if( iSid!=k ) continue;
      if( n==0 ){
        rEstLoop = (double)nLoop;
        if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
      }
      n++;
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
      fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
      rEstLoop *= rEst;
      fprintf(pArg->out, 
          "         nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
          nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
      );
    }
  }
  fprintf(pArg->out, "---------------------------\n");
#endif
}

/*
** Parameter azArray points to a zero-terminated array of strings. zStr
** points to a single nul-terminated string. Return non-zero if zStr
** is equal, according to strcmp(), to any of the strings in the array.
** Otherwise, return zero.
*/
1222
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235
1236
  const char *z;                  /* Used to check if this is an EXPLAIN */
  int *abYield = 0;               /* True if op is an OP_Yield */
  int nAlloc = 0;                 /* Allocated size of p->aiIndent[], abYield */
  int iOp;                        /* Index of operation in p->aiIndent[] */

  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
                           "NextIfOpen", "PrevIfOpen", 0 };
  const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 };

  const char *azGoto[] = { "Goto", 0 };

  /* Try to figure out if this is really an EXPLAIN statement. If this
  ** cannot be verified, return early.  */
  zSql = sqlite3_sql(pSql);
  if( zSql==0 ) return;
  for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);







|
>







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
  const char *z;                  /* Used to check if this is an EXPLAIN */
  int *abYield = 0;               /* True if op is an OP_Yield */
  int nAlloc = 0;                 /* Allocated size of p->aiIndent[], abYield */
  int iOp;                        /* Index of operation in p->aiIndent[] */

  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
                           "NextIfOpen", "PrevIfOpen", 0 };
  const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
                            "Rewind", 0 };
  const char *azGoto[] = { "Goto", 0 };

  /* Try to figure out if this is really an EXPLAIN statement. If this
  ** cannot be verified, return early.  */
  zSql = sqlite3_sql(pSql);
  if( zSql==0 ) return;
  for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1335
1336
1337
1338
1339
1340
1341
1342

1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
        const char *zStmtSql = sqlite3_sql(pStmt);
        fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
      }

      /* Show the EXPLAIN QUERY PLAN if .eqp is on */
      if( pArg && pArg->autoEQP ){
        sqlite3_stmt *pExplain;
        char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));

        rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
        if( rc==SQLITE_OK ){
          while( sqlite3_step(pExplain)==SQLITE_ROW ){
            fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
            fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
            fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
            fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
          }
        }
        sqlite3_finalize(pExplain);
        sqlite3_free(zEQP);
      }

      /* Output TESTCTRL_EXPLAIN text of requested */
      if( pArg && pArg->mode==MODE_Explain ){
        const char *zExplain = 0;
        sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
        if( zExplain && zExplain[0] ){
          fprintf(pArg->out, "%s", zExplain);
        }
      }

      /* If the shell is currently in ".explain" mode, gather the extra
      ** data required to add indents to the output.*/
      if( pArg && pArg->mode==MODE_Explain ){
        explain_data_prepare(pArg, pStmt);
      }

      /* perform the first step.  this will tell us if we







|
>













<
<
<
<
<
<
<
<
<







1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433









1434
1435
1436
1437
1438
1439
1440
        const char *zStmtSql = sqlite3_sql(pStmt);
        fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
      }

      /* Show the EXPLAIN QUERY PLAN if .eqp is on */
      if( pArg && pArg->autoEQP ){
        sqlite3_stmt *pExplain;
        char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
                                     sqlite3_sql(pStmt));
        rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
        if( rc==SQLITE_OK ){
          while( sqlite3_step(pExplain)==SQLITE_ROW ){
            fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
            fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
            fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
            fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
          }
        }
        sqlite3_finalize(pExplain);
        sqlite3_free(zEQP);
      }










      /* If the shell is currently in ".explain" mode, gather the extra
      ** data required to add indents to the output.*/
      if( pArg && pArg->mode==MODE_Explain ){
        explain_data_prepare(pArg, pStmt);
      }

      /* perform the first step.  this will tell us if we
1427
1428
1429
1430
1431
1432
1433





1434
1435
1436
1437
1438
1439
1440

      explain_data_delete(pArg);

      /* print usage stats if stats on */
      if( pArg && pArg->statsOn ){
        display_stats(db, pArg, 0);
      }






      /* Finalize the statement just executed. If this fails, save a 
      ** copy of the error message. Otherwise, set zSql to point to the
      ** next statement to execute. */
      rc2 = sqlite3_finalize(pStmt);
      if( rc!=SQLITE_NOMEM ) rc = rc2;
      if( rc==SQLITE_OK ){







>
>
>
>
>







1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514

      explain_data_delete(pArg);

      /* print usage stats if stats on */
      if( pArg && pArg->statsOn ){
        display_stats(db, pArg, 0);
      }

      /* print loop-counters if required */
      if( pArg && pArg->scanstatsOn ){
        display_scanstats(db, pArg);
      }

      /* Finalize the statement just executed. If this fails, save a 
      ** copy of the error message. Otherwise, set zSql to point to the
      ** next statement to execute. */
      rc2 = sqlite3_finalize(pStmt);
      if( rc!=SQLITE_NOMEM ) rc = rc2;
      if( rc==SQLITE_OK ){
1638
1639
1640
1641
1642
1643
1644

1645
1646
1647
1648
1649
1650
1651
  ".output ?FILENAME?     Send output to FILENAME or stdout\n"
  ".print STRING...       Print literal STRING\n"
  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
  ".quit                  Exit this program\n"
  ".read FILENAME         Execute SQL in FILENAME\n"
  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
  ".save FILE             Write in-memory database into FILE\n"

  ".schema ?TABLE?        Show the CREATE statements\n"
  "                         If TABLE specified, only show tables matching\n"
  "                         LIKE pattern TABLE.\n"
  ".separator STRING ?NL? Change separator used by output mode and .import\n"
  "                         NL is the end-of-line mark for CSV\n"
  ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
  ".show                  Show the current values for various settings\n"







>







1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
  ".output ?FILENAME?     Send output to FILENAME or stdout\n"
  ".print STRING...       Print literal STRING\n"
  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
  ".quit                  Exit this program\n"
  ".read FILENAME         Execute SQL in FILENAME\n"
  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
  ".save FILE             Write in-memory database into FILE\n"
  ".scanstats on|off      Turn sqlite3_stmt_scanstatus() metrics on or off\n"
  ".schema ?TABLE?        Show the CREATE statements\n"
  "                         If TABLE specified, only show tables matching\n"
  "                         LIKE pattern TABLE.\n"
  ".separator STRING ?NL? Change separator used by output mode and .import\n"
  "                         NL is the end-of-line mark for CSV\n"
  ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
  ".show                  Show the current values for various settings\n"
3019
3020
3021
3022
3023
3024
3025













3026
3027
3028
3029
3030
3031
3032
    }else{
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
      rc = 1;
    }
    sqlite3_close(pSrc);
  }else














  if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
    ShellState data;
    char *zErrMsg = 0;
    open_db(p, 0);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_Semi;







>
>
>
>
>
>
>
>
>
>
>
>
>







3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
    }else{
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
      rc = 1;
    }
    sqlite3_close(pSrc);
  }else


  if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
    if( nArg==2 ){
      p->scanstatsOn = booleanValue(azArg[1]);
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
      fprintf(stderr, "Warning: .scanstats not available in this build.\n");
#endif
    }else{
      fprintf(stderr, "Usage: .scanstats on|off\n");
      rc = 1;
    }
  }else

  if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
    ShellState data;
    char *zErrMsg = 0;
    open_db(p, 0);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_Semi;
3096
3097
3098
3099
3100
3101
3102









3103
3104
3105
3106
3107
3108
3109
    }else if( rc != SQLITE_OK ){
      fprintf(stderr,"Error: querying schema information\n");
      rc = 1;
    }else{
      rc = 0;
    }
  }else










#ifdef SQLITE_DEBUG
  /* Undocumented commands for internal testing.  Subject to change
  ** without notice. */
  if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
    if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
      int i, v;







>
>
>
>
>
>
>
>
>







3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
    }else if( rc != SQLITE_OK ){
      fprintf(stderr,"Error: querying schema information\n");
      rc = 1;
    }else{
      rc = 0;
    }
  }else


#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
  if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
    extern int sqlite3SelectTrace;
    sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
  }else
#endif


#ifdef SQLITE_DEBUG
  /* Undocumented commands for internal testing.  Subject to change
  ** without notice. */
  if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
    if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
      int i, v;
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
      }
      nPrintCol = 80/(maxlen+2);
      if( nPrintCol<1 ) nPrintCol = 1;
      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
      for(i=0; i<nPrintRow; i++){
        for(j=i; j<nRow; j+=nPrintRow){
          char *zSp = j<nPrintRow ? "" : "  ";
          fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
        }
        fprintf(p->out, "\n");
      }
    }
    for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
    sqlite3_free(azResult);
  }else







|







3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
      }
      nPrintCol = 80/(maxlen+2);
      if( nPrintCol<1 ) nPrintCol = 1;
      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
      for(i=0; i<nPrintRow; i++){
        for(j=i; j<nRow; j+=nPrintRow){
          char *zSp = j<nPrintRow ? "" : "  ";
          fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
        }
        fprintf(p->out, "\n");
      }
    }
    for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
    sqlite3_free(azResult);
  }else
3721
3722
3723
3724
3725
3726
3727

3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743

3744
3745
3746
3747
3748
3749
3750
      if( p->echoOn ) printf("%s\n", zSql);
      nSql = 0;
    }
  }
  if( nSql ){
    if( !_all_whitespace(zSql) ){
      fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);

    }
    free(zSql);
  }
  free(zLine);
  return errCnt>0;
}

/*
** Return a pathname which is the user's home directory.  A
** 0 return indicates an error of some kind.
*/
static char *find_home_dir(void){
  static char *home_dir = NULL;
  if( home_dir ) return home_dir;

#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)

  {
    struct passwd *pwent;
    uid_t uid = getuid();
    if( (pwent=getpwuid(uid)) != NULL) {
      home_dir = pwent->pw_dir;
    }
  }







>















|
>







3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
      if( p->echoOn ) printf("%s\n", zSql);
      nSql = 0;
    }
  }
  if( nSql ){
    if( !_all_whitespace(zSql) ){
      fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
      errCnt++;
    }
    free(zSql);
  }
  free(zLine);
  return errCnt>0;
}

/*
** Return a pathname which is the user's home directory.  A
** 0 return indicates an error of some kind.
*/
static char *find_home_dir(void){
  static char *home_dir = NULL;
  if( home_dir ) return home_dir;

#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
     && !defined(__RTP__) && !defined(_WRS_KERNEL)
  {
    struct passwd *pwent;
    uid_t uid = getuid();
    if( (pwent=getpwuid(uid)) != NULL) {
      home_dir = pwent->pw_dir;
    }
  }
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945



3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963












3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975



3976





3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
  return argv[i];
}

int main(int argc, char **argv){
  char *zErrMsg = 0;
  ShellState data;
  const char *zInitFile = 0;
  char *zFirstCmd = 0;
  int i;
  int rc = 0;
  int warnInmemoryDb = 0;




#if USE_SYSTEM_SQLITE+0!=1
  if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
    fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
            sqlite3_sourceid(), SQLITE_SOURCE_ID);
    exit(1);
  }
#endif
  Argv0 = argv[0];
  main_init(&data);
  stdin_is_interactive = isatty(0);

  /* Make sure we have a valid signal handler early, before anything
  ** else is done.
  */
#ifdef SIGINT
  signal(SIGINT, interrupt_handler);
#endif













  /* Do an initial pass through the command-line argument to locate
  ** the name of the database file, the name of the initialization file,
  ** the size of the alternative malloc heap,
  ** and the first command to execute.
  */
  for(i=1; i<argc; i++){
    char *z;
    z = argv[i];
    if( z[0]!='-' ){
      if( data.zDbFilename==0 ){
        data.zDbFilename = z;



        continue;





      }
      if( zFirstCmd==0 ){
        zFirstCmd = z;
        continue;
      }
      fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
      fprintf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
    if( z[1]=='-' ) z++;
    if( strcmp(z,"-separator")==0
     || strcmp(z,"-nullvalue")==0
     || strcmp(z,"-newline")==0
     || strcmp(z,"-cmd")==0
    ){







<



>
>
>


















>
>
>
>
>
>
>
>
>
>
>
>












>
>
>
|
>
>
>
>
>
|
<
|
<

<
<
<







4034
4035
4036
4037
4038
4039
4040

4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098

4099

4100



4101
4102
4103
4104
4105
4106
4107
  return argv[i];
}

int main(int argc, char **argv){
  char *zErrMsg = 0;
  ShellState data;
  const char *zInitFile = 0;

  int i;
  int rc = 0;
  int warnInmemoryDb = 0;
  int readStdin = 1;
  int nCmd = 0;
  char **azCmd = 0;

#if USE_SYSTEM_SQLITE+0!=1
  if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
    fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
            sqlite3_sourceid(), SQLITE_SOURCE_ID);
    exit(1);
  }
#endif
  Argv0 = argv[0];
  main_init(&data);
  stdin_is_interactive = isatty(0);

  /* Make sure we have a valid signal handler early, before anything
  ** else is done.
  */
#ifdef SIGINT
  signal(SIGINT, interrupt_handler);
#endif

#ifdef SQLITE_SHELL_DBNAME_PROC
  {
    /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
    ** of a C-function that will provide the name of the database file.  Use
    ** this compile-time option to embed this shell program in larger
    ** applications. */
    extern void SQLITE_SHELL_DBNAME_PROC(const char**);
    SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
    warnInmemoryDb = 0;
  }
#endif

  /* Do an initial pass through the command-line argument to locate
  ** the name of the database file, the name of the initialization file,
  ** the size of the alternative malloc heap,
  ** and the first command to execute.
  */
  for(i=1; i<argc; i++){
    char *z;
    z = argv[i];
    if( z[0]!='-' ){
      if( data.zDbFilename==0 ){
        data.zDbFilename = z;
      }else{
        /* Excesss arguments are interpreted as SQL (or dot-commands) and
        ** mean that nothing is read from stdin */
        readStdin = 0;
        nCmd++;
        azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
        if( azCmd==0 ){
          fprintf(stderr, "out of memory\n");
          exit(1);
        }

        azCmd[nCmd-1] = z;

      }



    }
    if( z[1]=='-' ) z++;
    if( strcmp(z,"-separator")==0
     || strcmp(z,"-nullvalue")==0
     || strcmp(z,"-newline")==0
     || strcmp(z,"-cmd")==0
    ){
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
    warnInmemoryDb = argc==1;
#else
    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
    return 1;
#endif
#ifdef SQLITE_SHELL_DBNAME_PROC
    { extern void SQLITE_SHELL_DBNAME_PROC(const char**);
      SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
      warnInmemoryDb = 0; }
#endif
  }
  data.out = stdout;

  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.







<
<
<
<
<







4184
4185
4186
4187
4188
4189
4190





4191
4192
4193
4194
4195
4196
4197
#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
    warnInmemoryDb = argc==1;
#else
    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
    return 1;
#endif





  }
  data.out = stdout;

  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.
4135
4136
4137
4138
4139
4140
4141


4142
4143
4144
4145
4146
4147
4148
      data.showHeader = 0;
    }else if( strcmp(z,"-echo")==0 ){
      data.echoOn = 1;
    }else if( strcmp(z,"-eqp")==0 ){
      data.autoEQP = 1;
    }else if( strcmp(z,"-stats")==0 ){
      data.statsOn = 1;


    }else if( strcmp(z,"-bail")==0 ){
      bail_on_error = 1;
    }else if( strcmp(z,"-version")==0 ){
      printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
      return 0;
    }else if( strcmp(z,"-interactive")==0 ){
      stdin_is_interactive = 1;







>
>







4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
      data.showHeader = 0;
    }else if( strcmp(z,"-echo")==0 ){
      data.echoOn = 1;
    }else if( strcmp(z,"-eqp")==0 ){
      data.autoEQP = 1;
    }else if( strcmp(z,"-stats")==0 ){
      data.statsOn = 1;
    }else if( strcmp(z,"-scanstats")==0 ){
      data.scanstatsOn = 1;
    }else if( strcmp(z,"-bail")==0 ){
      bail_on_error = 1;
    }else if( strcmp(z,"-version")==0 ){
      printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
      return 0;
    }else if( strcmp(z,"-interactive")==0 ){
      stdin_is_interactive = 1;
4167
4168
4169
4170
4171
4172
4173




4174
4175
4176
4177
4178
4179
4180
#ifdef SQLITE_ENABLE_MULTIPLEX
    }else if( strcmp(z,"-multiplex")==0 ){
      i++;
#endif
    }else if( strcmp(z,"-help")==0 ){
      usage(1);
    }else if( strcmp(z,"-cmd")==0 ){




      if( i==argc-1 ) break;
      z = cmdline_option_value(argc,argv,++i);
      if( z[0]=='.' ){
        rc = do_meta_command(z, &data);
        if( rc && bail_on_error ) return rc==2 ? 0 : rc;
      }else{
        open_db(&data, 0);







>
>
>
>







4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
#ifdef SQLITE_ENABLE_MULTIPLEX
    }else if( strcmp(z,"-multiplex")==0 ){
      i++;
#endif
    }else if( strcmp(z,"-help")==0 ){
      usage(1);
    }else if( strcmp(z,"-cmd")==0 ){
      /* Run commands that follow -cmd first and separately from commands
      ** that simply appear on the command-line.  This seems goofy.  It would
      ** be better if all commands ran in the order that they appear.  But
      ** we retain the goofy behavior for historical compatibility. */
      if( i==argc-1 ) break;
      z = cmdline_option_value(argc,argv,++i);
      if( z[0]=='.' ){
        rc = do_meta_command(z, &data);
        if( rc && bail_on_error ) return rc==2 ? 0 : rc;
      }else{
        open_db(&data, 0);
4190
4191
4192
4193
4194
4195
4196
4197


4198
4199

4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213


4214
4215
4216
4217
4218
4219
4220
    }else{
      fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
      fprintf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
  }

  if( zFirstCmd ){


    /* Run just the command that follows the database name
    */

    if( zFirstCmd[0]=='.' ){
      rc = do_meta_command(zFirstCmd, &data);
      if( rc==2 ) rc = 0;
    }else{
      open_db(&data, 0);
      rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
      if( zErrMsg!=0 ){
        fprintf(stderr,"Error: %s\n", zErrMsg);
        return rc!=0 ? rc : 1;
      }else if( rc!=0 ){
        fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
        return rc;
      }
    }


  }else{
    /* Run commands received from standard input
    */
    if( stdin_is_interactive ){
      char *zHome;
      char *zHistory = 0;
      int nHistory;







|
>
>
|

>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>







4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
    }else{
      fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
      fprintf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
  }

  if( !readStdin ){
    /* Run all arguments that do not begin with '-' as if they were separate
    ** command-line inputs, except for the argToSkip argument which contains
    ** the database filename.
    */
    for(i=0; i<nCmd; i++){
      if( azCmd[i][0]=='.' ){
        rc = do_meta_command(azCmd[i], &data);
        if( rc ) return rc==2 ? 0 : rc;
      }else{
        open_db(&data, 0);
        rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
        if( zErrMsg!=0 ){
          fprintf(stderr,"Error: %s\n", zErrMsg);
          return rc!=0 ? rc : 1;
        }else if( rc!=0 ){
          fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
          return rc;
        }
      }
    }
    free(azCmd);
  }else{
    /* Run commands received from standard input
    */
    if( stdin_is_interactive ){
      char *zHome;
      char *zHistory = 0;
      int nHistory;
Changes to src/shun.c.
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void shun_page(void){
  Stmt q;
  int cnt = 0;
  const char *zUuid = P("uuid");
  const char *zShun = P("shun");
  const char *zAccept = P("accept");
  const char *zRcvid = P("rcvid");
  int nRcvid;
  int nUuid;
  int numRows = 3;
  char *zCanonical = 0;

  login_check_credentials();
  if( !g.perm.Admin ){
    login_needed();
  }







|
<







41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
void shun_page(void){
  Stmt q;
  int cnt = 0;
  const char *zUuid = P("uuid");
  const char *zShun = P("shun");
  const char *zAccept = P("accept");
  const char *zRcvid = P("rcvid");
  int nRcvid = 0;

  int numRows = 3;
  char *zCanonical = 0;

  login_check_credentials();
  if( !g.perm.Admin ){
    login_needed();
  }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
        j++;
      }
      i++;
    }
    zCanonical[j+1] = zCanonical[j] = 0;
    p = zCanonical;
    while( *p ){
      nUuid = strlen(p);
      if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
        @ <p class="generalError">Error: Bad artifact IDs.</p>
        fossil_free(zCanonical);
        zCanonical = 0;
        break;
      }else{
        canonical16(p, UUID_SIZE);
        p += UUID_SIZE+1;
      }
    }
    zUuid = zCanonical;
  }
  style_header("Shunned Artifacts");
  if( zUuid && P("sub") ){
    const char *p = zUuid;
    int allExist = 1;
    login_verify_csrf_secret();
    while( *p ){
      db_multi_exec("DELETE FROM shun WHERE uuid='%s'", p);
      if( !db_exists("SELECT 1 FROM blob WHERE uuid='%s'", p) ){
        allExist = 0;
      }
      p += UUID_SIZE+1;
    }
    if( allExist ){
      @ <p class="noMoreShun">Artifact(s)<br />
      for( p = zUuid ; *p ; p += UUID_SIZE+1 ){







|


















|
|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
        j++;
      }
      i++;
    }
    zCanonical[j+1] = zCanonical[j] = 0;
    p = zCanonical;
    while( *p ){
      int nUuid = strlen(p);
      if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
        @ <p class="generalError">Error: Bad artifact IDs.</p>
        fossil_free(zCanonical);
        zCanonical = 0;
        break;
      }else{
        canonical16(p, UUID_SIZE);
        p += UUID_SIZE+1;
      }
    }
    zUuid = zCanonical;
  }
  style_header("Shunned Artifacts");
  if( zUuid && P("sub") ){
    const char *p = zUuid;
    int allExist = 1;
    login_verify_csrf_secret();
    while( *p ){
      db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
      if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
        allExist = 0;
      }
      p += UUID_SIZE+1;
    }
    if( allExist ){
      @ <p class="noMoreShun">Artifact(s)<br />
      for( p = zUuid ; *p ; p += UUID_SIZE+1 ){
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  if( zUuid && P("add") ){
    const char *p = zUuid;
    int rid, tagid;
    login_verify_csrf_secret();
    while( *p ){
      db_multi_exec(
        "INSERT OR IGNORE INTO shun(uuid,mtime)"
        " VALUES('%s', now())", p);
      db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
      rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
      if( rid ){
        db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
      }
      tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='tkt-%q'", p);
      if( tagid ){







|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  if( zUuid && P("add") ){
    const char *p = zUuid;
    int rid, tagid;
    login_verify_csrf_secret();
    while( *p ){
      db_multi_exec(
        "INSERT OR IGNORE INTO shun(uuid,mtime)"
        " VALUES(%Q, now())", p);
      db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
      rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
      if( rid ){
        db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
      }
      tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='tkt-%q'", p);
      if( tagid ){
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
    }
    @ have been shunned.  They will no longer be pushed.
    @ They will be removed from the repository the next time the repository
    @ is rebuilt using the <b>fossil rebuild</b> command-line</p>
  }
  if( zRcvid ){
    nRcvid = atoi(zRcvid);
    numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", nRcvid);

  }
  @ <p>A shunned artifact will not be pushed nor accepted in a pull and the
  @ artifact content will be purged from the repository the next time the
  @ repository is rebuilt.  A list of shunned artifacts can be seen at the
  @ bottom of this page.</p>
  @
  @ <a name="addshun"></a>







|
>







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    }
    @ have been shunned.  They will no longer be pushed.
    @ They will be removed from the repository the next time the repository
    @ is rebuilt using the <b>fossil rebuild</b> command-line</p>
  }
  if( zRcvid ){
    nRcvid = atoi(zRcvid);
    numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d",
                     nRcvid);
  }
  @ <p>A shunned artifact will not be pushed nor accepted in a pull and the
  @ artifact content will be purged from the repository the next time the
  @ repository is rebuilt.  A list of shunned artifacts can be seen at the
  @ bottom of this page.</p>
  @
  @ <a name="addshun"></a>
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  @ <blockquote>
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
  if( zShun ){
    if( strlen(zShun) ){
      @ %h(zShun)
    }else if( zRcvid ){
      db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
      while( db_step(&q)==SQLITE_ROW ){
        @ %s(db_column_text(&q, 0))
      }
      db_finalize(&q);
    }
  }







|







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  @ <blockquote>
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
  if( zShun ){
    if( strlen(zShun) ){
      @ %h(zShun)
    }else if( nRcvid ){
      db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
      while( db_step(&q)==SQLITE_ROW ){
        @ %s(db_column_text(&q, 0))
      }
      db_finalize(&q);
    }
  }
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  @ <blockquote>
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
  if( zAccept ){
    if( strlen(zAccept) ){
      @ %h(zAccept)
    }else if( zRcvid ){
      db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
      while( db_step(&q)==SQLITE_ROW ){
        @ %s(db_column_text(&q, 0))
      }
      db_finalize(&q);
    }
  }







|







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  @ <blockquote>
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
  if( zAccept ){
    if( strlen(zAccept) ){
      @ %h(zAccept)
    }else if( nRcvid ){
      db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
      while( db_step(&q)==SQLITE_ROW ){
        @ %s(db_column_text(&q, 0))
      }
      db_finalize(&q);
    }
  }
Changes to src/skins.c.
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
      );
    }
    seen = 0;
    for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
      if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
        seen = 1;
        zCurrent = aBuiltinSkin[i].zValue;
        db_multi_exec("%s", zCurrent);
        break;
      }
    }
    if( !seen ){
      zName = skinVarName(z,0);
      zCurrent = db_get(zName, 0);
      db_multi_exec("%s", zCurrent);
    }
  }

  style_header("Skins");
  if( zErr ){
    @ <p><font color="red">%h(zErr)</font></p>
  }







|






|







1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
      );
    }
    seen = 0;
    for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
      if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
        seen = 1;
        zCurrent = aBuiltinSkin[i].zValue;
        db_multi_exec("%s", zCurrent/*safe-for-%s*/);
        break;
      }
    }
    if( !seen ){
      zName = skinVarName(z,0);
      zCurrent = db_get(zName, 0);
      db_multi_exec("%s", zCurrent/*safe-for-%s*/);
    }
  }

  style_header("Skins");
  if( zErr ){
    @ <p><font color="red">%h(zErr)</font></p>
  }
Changes to src/sqlcmd.c.
115
116
117
118
119
120
121


122
123
124
125
126
127
128



129
130
131
132
133




134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156



157
158
159
160
161
162
163
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
  sqlite3 *db,
  const char **pzErrMsg,
  const void *notUsed
){


  sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0,
                          sqlcmd_content, 0, 0);
  sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
                          sqlcmd_compress, 0, 0);
  sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0,
                          sqlcmd_decompress, 0, 0);
  re_add_sql_func(db);



#if USE_SYSTEM_SQLITE+0==1
  sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, g.maxWorkerThreads);
#endif
  g.repositoryOpen = 1;
  g.db = db;




  return SQLITE_OK;
}

/*
** COMMAND: sqlite3
**
** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS?
**
** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS.
** If DATABASE is omitted, then the repository that serves the working
** directory is opened.
**
** WARNING:  Careless use of this command can corrupt a Fossil repository
** in ways that are unrecoverable.  Be sure you know what you are doing before
** running any SQL commands that modifies the repository database.
*/
void cmd_sqlite3(void){
  extern int sqlite3_shell(int, char**);
  db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
  db_close(1);
  sqlite3_shutdown();
  sqlite3_shell(g.argc-1, g.argv+1);

  g.db = 0;



}

/*
** This routine is called by the patched sqlite3 command-line shell in order
** to load the name and database connection for the open Fossil database.
*/
void fossil_open(const char **pzRepoName){







>
>







>
>
>



|
|
>
>
>
>
|





|

|
|
|











>

>
>
>







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
  sqlite3 *db,
  const char **pzErrMsg,
  const void *notUsed
){
  char *zSql;
  int rc = SQLITE_OK;
  sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0,
                          sqlcmd_content, 0, 0);
  sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
                          sqlcmd_compress, 0, 0);
  sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0,
                          sqlcmd_decompress, 0, 0);
  re_add_sql_func(db);
  g.zMainDbType = "repository";
  g.repositoryOpen = 1;
  g.db = db;
#if USE_SYSTEM_SQLITE+0==1
  sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, g.maxWorkerThreads);
#endif
  db_open_config(1);
  if( g.zLocalDbName ){
    zSql = sqlite3_mprintf("ATTACH %Q AS localdb;", g.zLocalDbName);
    rc = sqlite3_exec(db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }
  return rc;
}

/*
** COMMAND: sqlite3
**
** Usage: %fossil sqlite3 ?SQL-COMMANDS? ?OPTIONS?
**
** Run the standalone sqlite3 command-line shell on the repository database
** for the current checkout, or whatever repository is specified by the
** -R command-line option.
**
** WARNING:  Careless use of this command can corrupt a Fossil repository
** in ways that are unrecoverable.  Be sure you know what you are doing before
** running any SQL commands that modifies the repository database.
*/
void cmd_sqlite3(void){
  extern int sqlite3_shell(int, char**);
  db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
  db_close(1);
  sqlite3_shutdown();
  sqlite3_shell(g.argc-1, g.argv+1);
  sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
  g.db = 0;
  g.zMainDbType = 0;
  g.repositoryOpen = 0;
  g.localOpen = 0;
}

/*
** This routine is called by the patched sqlite3 command-line shell in order
** to load the name and database connection for the open Fossil database.
*/
void fossil_open(const char **pzRepoName){
Changes to src/sqlite3.c.
1
2
3
4
5
6
7
8
9
10
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.8.7.  By combining all the individual C code files into this 
** single large file, the entire code can be compiled as a single translation
** unit.  This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately.  Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
**
** This file is all you need to compile SQLite.  To use SQLite in other


|







1
2
3
4
5
6
7
8
9
10
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.8.8.  By combining all the individual C code files into this 
** single large file, the entire code can be compiled as a single translation
** unit.  This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately.  Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
**
** This file is all you need to compile SQLite.  To use SQLite in other
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# define SQLITE_API
#endif


/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental.  New applications
** should not use deprecated interfaces - they are support for backwards
** compatibility only.  Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
** These macros used to resolve to various kinds of compiler magic that
** would generate warning messages when they were used.  But that
** compiler magic ended up generating such a flurry of bug reports
** that we have taken it all out and gone back to using simple







|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# define SQLITE_API
#endif


/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental.  New applications
** should not use deprecated interfaces - they are supported for backwards
** compatibility only.  Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
** These macros used to resolve to various kinds of compiler magic that
** would generate warning messages when they were used.  But that
** compiler magic ended up generating such a flurry of bug reports
** that we have taken it all out and gone back to using simple
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.7"
#define SQLITE_VERSION_NUMBER 3008007
#define SQLITE_SOURCE_ID      "2014-09-20 00:35:05 59e2c9df02d7e988c5ad44c560ead1e5288b12e7"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|
|
|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.8"
#define SQLITE_VERSION_NUMBER 3008008
#define SQLITE_SOURCE_ID      "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
1624
1625
1626
1627
1628
1629
1630
1631
1632

1633
1634
1635
1636
1637
1638
1639
1640

1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663

1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674

1675
1676






1677
1678
1679
1680

1681
1682

1683
1684
1685
1686
1687


1688
1689

1690

1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702




1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
** ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** it is not possible to set the Serialized [threading mode] and
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
**
** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure.  The argument specifies

** alternative low-level memory allocation routines to be used in place of
** the memory allocation routines built into SQLite.)^ ^SQLite makes
** its own private copy of the content of the [sqlite3_mem_methods] structure
** before the [sqlite3_config()] call returns.</dd>
**
** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure.  The [sqlite3_mem_methods]

** structure is filled with the currently defined memory allocation routines.)^
** This option can be used to overload the default memory allocation
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^This option takes single argument of type int, interpreted as a 
** boolean, which enables or disables the collection of memory allocation 
** statistics. ^(When memory allocation statistics are disabled, the 
** following SQLite interfaces become non-operational:
**   <ul>
**   <li> [sqlite3_memory_used()]
**   <li> [sqlite3_memory_highwater()]
**   <li> [sqlite3_soft_heap_limit64()]
**   <li> [sqlite3_status()]
**   </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for

** scratch memory.  There are three arguments:  A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).  The sz
** argument must be a multiple of 16.
** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will use no more than two scratch buffers per thread.  So
** N should be set to twice the expected maximum number of threads.
** ^SQLite will never require a scratch buffer that is more than 6
** times the database page size. ^If SQLite needs needs additional

** scratch memory beyond what is provided by this configuration option, then 
** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>






**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** the database page cache with the default page cache implementation.  

** This configuration should not be used if an application-define page
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.

** There are three arguments to this option: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 32768) plus a little extra for each
** page header.  ^The page header size is 20 to 40 bytes depending on


** the host architecture.  ^It is harmless, apart from the wasted memory,
** to make sz a little too large.  The first

** argument should point to an allocation of at least sz*N bytes of memory.

** ^SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache.  ^If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.
** The pointer in the first argument must
** be aligned to an 8-byte boundary or subsequent behavior of SQLite
** will be undefined.</dd>
**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^This option specifies a static memory buffer that SQLite will use
** for all of its dynamic memory allocation needs beyond those provided
** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].




** There are three arguments: An 8-byte aligned pointer to the memory,
** the number of bytes in the memory buffer, and the minimum allocation size.
** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
** allocator is engaged to handle all of SQLites memory allocation needs.
** The first pointer (the memory pointer) must be aligned to an 8-byte
** boundary or subsequent behavior of SQLite will be undefined.
** The minimum allocation size is capped at 2**12. Reasonable values
** for the minimum allocation size are 2**5 through 2**8.</dd>
**
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
** alternative low-level mutex routines to be used in place
** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
** content of the [sqlite3_mutex_methods] structure before the call to
** [sqlite3_config()] returns. ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure.  The
** [sqlite3_mutex_methods]
** structure is filled with the currently defined mutex routines.)^
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.   ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(This option takes two arguments that determine the default
** memory allocation for the lookaside memory allocator on each
** [database connection].  The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.)^  ^(This option sets the
** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** verb to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(This option takes a single argument which is a pointer to
** an [sqlite3_pcache_methods2] object.  This object specifies the interface
** to a custom page cache implementation.)^  ^SQLite makes a copy of the
** object and uses it for page cache memory allocations.</dd>
**
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** [sqlite3_pcache_methods2] object.  SQLite copies of the current
** page cache implementation into that object.)^ </dd>
**
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
** global [error log].
** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
** function with a call signature of void(*)(void*,int,const char*), 







|
|
>






|
|
>






|
|
|













|
>
|


|
<


|
<
|
|
>

|
>
>
>
>
>
>


|
|
>

|
>
|


|
|
>
>
|
|
>
|
>



|
<
<
<


|
|
|
>
>
>
>
|




|
<







|
|
|









|
|











|
|
|

|
|
|



|
|
|
|


|
|







1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670

1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708



1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723

1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
** ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** it is not possible to set the Serialized [threading mode] and
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
**
** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
** <dd> ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is 
** a pointer to an instance of the [sqlite3_mem_methods] structure.
** The argument specifies
** alternative low-level memory allocation routines to be used in place of
** the memory allocation routines built into SQLite.)^ ^SQLite makes
** its own private copy of the content of the [sqlite3_mem_methods] structure
** before the [sqlite3_config()] call returns.</dd>
**
** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which
** is a pointer to an instance of the [sqlite3_mem_methods] structure.
** The [sqlite3_mem_methods]
** structure is filled with the currently defined memory allocation routines.)^
** This option can be used to overload the default memory allocation
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
** memory allocation statistics. ^(When memory allocation statistics are disabled, the 
** following SQLite interfaces become non-operational:
**   <ul>
**   <li> [sqlite3_memory_used()]
**   <li> [sqlite3_memory_highwater()]
**   <li> [sqlite3_soft_heap_limit64()]
**   <li> [sqlite3_status()]
**   </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
** that SQLite can use for scratch memory.  ^(There are three arguments
** to SQLITE_CONFIG_SCRATCH:  A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).)^

** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will not use more than one scratch buffers per thread.

** ^SQLite will never request a scratch buffer that is more than 6
** times the database page size.
** ^If SQLite needs needs additional
** scratch memory beyond what is provided by this configuration option, then 
** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
** ^When the application provides any amount of scratch memory using
** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
** [sqlite3_malloc|heap allocations].
** This can help [Robson proof|prevent memory allocation failures] due to heap
** fragmentation in low-memory embedded systems.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
** that SQLite can use for the database page cache with the default page
** cache implementation.  
** This configuration should not be used if an application-define page
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
** configuration option.
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 32768) plus some extra bytes for each
** page header.  ^The number of extra bytes needed by the page header
** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option 
** to [sqlite3_config()].
** ^It is harmless, apart from the wasted memory,
** for the sz parameter to be larger than necessary.  The first
** argument should pointer to an 8-byte aligned block of memory that
** is at least sz*N bytes of memory, otherwise subsequent behavior is
** undefined.
** ^SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache.  ^If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>



**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
** that SQLite will use for all of its dynamic memory allocation needs
** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
** ^There are three arguments to SQLITE_CONFIG_HEAP:
** An 8-byte aligned pointer to the memory,
** the number of bytes in the memory buffer, and the minimum allocation size.
** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
** memory pointer is not NULL then the alternative memory

** allocator is engaged to handle all of SQLites memory allocation needs.
** The first pointer (the memory pointer) must be aligned to an 8-byte
** boundary or subsequent behavior of SQLite will be undefined.
** The minimum allocation size is capped at 2**12. Reasonable values
** for the minimum allocation size are 2**5 through 2**8.</dd>
**
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
** pointer to an instance of the [sqlite3_mutex_methods] structure.
** The argument specifies alternative low-level mutex routines to be used in place
** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
** content of the [sqlite3_mutex_methods] structure before the call to
** [sqlite3_config()] returns. ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which
** is a pointer to an instance of the [sqlite3_mutex_methods] structure.  The
** [sqlite3_mutex_methods]
** structure is filled with the currently defined mutex routines.)^
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.   ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
** the default size of lookaside memory on each [database connection].
** The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.)^  ^(SQLITE_CONFIG_LOOKASIDE
** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** option to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is 
** a pointer to an [sqlite3_pcache_methods2] object.  This object specifies
** the interface to a custom page cache implementation.)^
** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
**
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which
** is a pointer to an [sqlite3_pcache_methods2] object.  SQLite copies of the current
** page cache implementation into that object.)^ </dd>
**
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
** global [error log].
** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
** function with a call signature of void(*)(void*,int,const char*), 
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797

1798
1799
1800
1801
1802
1803
1804
1805
** log message after formatting via [sqlite3_snprintf()].
** The SQLite logging interface is not reentrant; the logger function
** supplied by the application must not invoke any SQLite interface.
** In a multi-threaded application, the application-defined logger
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for

** full table scans in the query optimizer.  ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.







|
|
|
|









|
|
>
|







1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
** log message after formatting via [sqlite3_snprintf()].
** The SQLite logging interface is not reentrant; the logger function
** supplied by the application must not invoke any SQLite interface.
** In a multi-threaded application, the application-defined logger
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int.
** If non-zero, then URI handling is globally enabled. If the parameter is zero,
** then URI handling is globally disabled.)^ ^If URI handling is globally enabled,
** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd>^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer
** argument which is interpreted as a boolean in order to enable or disable
** the use of covering indices for full table scans in the query optimizer.
** ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850









1851
1852
1853
1854
1855
1856
1857
** <dt>SQLITE_CONFIG_MMAP_SIZE
** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
** cannot be changed at run-time.  Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
**
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
** <dd>^This option is only available if SQLite is compiled for Windows
** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
** </dl>









*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */







|
|






|
|
|


>
>
>
>
>
>
>
>
>







1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
** <dt>SQLITE_CONFIG_MMAP_SIZE
** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
** will be silently truncated if necessary so that it does not exceed the
** compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
**
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
** </dl>
**
** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
** is a pointer to an integer and writes into that integer the number of extra
** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of
** extra space required can change depending on the compiler,
** target platform, and SQLite version.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
1868
1869
1870
1871
1872
1873
1874

1875
1876
1877
1878
1879
1880
1881
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */


/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**







>







1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004



2005
2006
2007
2008
2009
2010
2011



2012
2013
2014
2015
2016
2017


2018

2019
2020
2021
2022
2023
2024
2025
2026
2027

2028
2029

2030
2031
2032




2033
2034
2035
2036

2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057


2058
2059

2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
** last insert [rowid].
*/
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);

/*
** CAPI3REF: Count The Number Of Rows Modified
**
** ^This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
** on the [database connection] specified by the first parameter.



** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
** or [DELETE] statement are counted.  Auxiliary changes caused by
** triggers or [foreign key actions] are not counted.)^ Use the
** [sqlite3_total_changes()] function to find the total number of changes
** including changes caused by triggers and foreign key actions.
**
** ^Changes to a view that are simulated by an [INSTEAD OF trigger]



** are not counted.  Only real table changes are counted.
**
** ^(A "row change" is a change to a single row of a single table
** caused by an INSERT, DELETE, or UPDATE statement.  Rows that
** are changed as side effects of [REPLACE] constraint resolution,
** rollback, ABORT processing, [DROP TABLE], or by any other


** mechanisms do not count as direct row changes.)^

**
** A "trigger context" is a scope of execution that begins and
** ends with the script of a [CREATE TRIGGER | trigger]. 
** Most SQL statements are
** evaluated outside of any trigger.  This is the "top level"
** trigger context.  If a trigger fires from the top level, a
** new trigger context is entered for the duration of that one
** trigger.  Subtriggers create subcontexts for their duration.
**

** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
** not create a new trigger context.

**
** ^This function returns the number of direct row changes in the
** most recent INSERT, UPDATE, or DELETE statement within the same




** trigger context.
**
** ^Thus, when called from the top level, this function returns the
** number of changes in the most recent INSERT, UPDATE, or DELETE

** that also occurred at the top level.  ^(Within the body of a trigger,
** the sqlite3_changes() interface can be called to find the number of
** changes in the most recently completed INSERT, UPDATE, or DELETE
** statement within the body of the same trigger.
** However, the number returned does not include changes
** caused by subtriggers since those have their own context.)^
**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_changes(sqlite3*);

/*
** CAPI3REF: Total Number Of Rows Modified
**
** ^This function returns the number of row changes caused by [INSERT],
** [UPDATE] or [DELETE] statements since the [database connection] was opened.


** ^(The count returned by sqlite3_total_changes() includes all changes
** from all [CREATE TRIGGER | trigger] contexts and changes made by

** [foreign key actions]. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing.  The
** count does not include rows of views that fire an [INSTEAD OF trigger],
** though if the INSTEAD OF trigger makes changes of its own, those changes 
** are counted.)^
** ^The sqlite3_total_changes() function counts the changes as soon as
** the statement that makes them is completed (when the statement handle
** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
**
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/







|
|
|
>
>
>
|
|
|
<
<
|
|
>
>
>
|

<
<
<
<
>
>
|
>
|
<
<
<
<
<
<
<
|
>
|
<
>
|
<
|
>
>
>
>
|
|
|
|
>
|
|
<
|
<
<













|
|
>
>
|
<
>
|
<
<
|
|
|
<
<
<
|







2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035


2036
2037
2038
2039
2040
2041
2042




2043
2044
2045
2046
2047







2048
2049
2050

2051
2052

2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064

2065


2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083

2084
2085


2086
2087
2088



2089
2090
2091
2092
2093
2094
2095
2096
** last insert [rowid].
*/
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);

/*
** CAPI3REF: Count The Number Of Rows Modified
**
** ^This function returns the number of rows modified, inserted or
** deleted by the most recently completed INSERT, UPDATE or DELETE
** statement on the database connection specified by the only parameter.
** ^Executing any other type of SQL statement does not modify the value
** returned by this function.
**
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], 
** [foreign key actions] or [REPLACE] constraint resolution are not counted.


** 
** Changes to a view that are intercepted by 
** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value 
** returned by sqlite3_changes() immediately after an INSERT, UPDATE or 
** DELETE statement run on a view is always zero. Only changes made to real 
** tables are counted.
**




** Things are more complicated if the sqlite3_changes() function is
** executed while a trigger program is running. This may happen if the
** program uses the [changes() SQL function], or if some other callback
** function invokes sqlite3_changes() directly. Essentially:
** 







** <ul>
**   <li> ^(Before entering a trigger program the value returned by
**        sqlite3_changes() function is saved. After the trigger program 

**        has finished, the original value is restored.)^
** 

**   <li> ^(Within a trigger program each INSERT, UPDATE and DELETE 
**        statement sets the value returned by sqlite3_changes() 
**        upon completion as normal. Of course, this value will not include 
**        any changes performed by sub-triggers, as the sqlite3_changes() 
**        value will be saved and restored after each sub-trigger has run.)^
** </ul>
** 
** ^This means that if the changes() SQL function (or similar) is used
** by the first INSERT, UPDATE or DELETE statement within a trigger, it 
** returns the value as set when the calling statement began executing.
** ^If it is used by the second or subsequent such statement within a trigger 
** program, the value returned reflects the number of rows modified by the 

** previous INSERT, UPDATE or DELETE statement within the same trigger.


**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_changes(sqlite3*);

/*
** CAPI3REF: Total Number Of Rows Modified
**
** ^This function returns the total number of rows inserted, modified or
** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
** since the database connection was opened, including those executed as
** part of trigger programs. ^Executing any other type of SQL statement
** does not affect the value returned by sqlite3_total_changes().

** 
** ^Changes made as part of [foreign key actions] are included in the


** count, but those made as part of REPLACE constraint resolution are
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
** are not counted.



** 
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550

2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random [ROWID | ROWIDs] when inserting new records into a table that
** already uses the largest possible [ROWID].  The PRNG is also used for
** the build-in random() and randomblob() SQL functions.  This interface allows
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
** ^If N is less than one, then P can be a NULL pointer.
**
** ^If this routine has not been previously called or if the previous
** call had N less than one, then the PRNG is seeded using randomness

** obtained from the xRandomness method of the default [sqlite3_vfs] object.
** ^If the previous call to this routine had an N of 1 or more then
** the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
SQLITE_API void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks







|


|
>
|
|
|







2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random [ROWID | ROWIDs] when inserting new records into a table that
** already uses the largest possible [ROWID].  The PRNG is also used for
** the build-in random() and randomblob() SQL functions.  This interface allows
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
** ^The P parameter can be a NULL pointer.
**
** ^If this routine has not been previously called or if the previous
** call had N less than one or a NULL pointer for P, then the PRNG is
** seeded using randomness obtained from the xRandomness method of
** the default [sqlite3_vfs] object.
** ^If the previous call to this routine had an N of 1 or more and a
** non-NULL P then the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
SQLITE_API void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
** object.)^ ^(If the database is opened (and/or created) successfully, then
** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.)^ ^The
** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
** an English language description of the error following a failure of any
** of the sqlite3_open() routines.
**
** ^The default encoding for the database will be UTF-8 if
** sqlite3_open() or sqlite3_open_v2() is called and
** UTF-16 in the native byte order if sqlite3_open16() is used.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
** passing it to [sqlite3_close()] when it is no longer required.
**
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control







|
|
|







2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
** object.)^ ^(If the database is opened (and/or created) successfully, then
** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.)^ ^The
** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
** an English language description of the error following a failure of any
** of the sqlite3_open() routines.
**
** ^The default encoding will be UTF-8 for databases created using
** sqlite3_open() or sqlite3_open_v2().  ^The default encoding for databases
** created using sqlite3_open16() will be UTF-16 in the native byte order.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
** passing it to [sqlite3_close()] when it is no longer required.
**
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891

2892
2893
2894
2895
2896
2897
2898
2899
** present, is ignored.
**
** ^SQLite uses the path component of the URI as the name of the disk file
** which contains the database. ^If the path begins with a '/' character, 
** then it is interpreted as an absolute path. ^If the path does not begin 
** with a '/' (meaning that the authority section is omitted from the URI)
** then the path is interpreted as a relative path. 
** ^On windows, the first component of an absolute path 
** is a drive specification (e.g. "C:").
**
** [[core URI query parameters]]
** The query component of a URI may contain parameters that are interpreted
** either by SQLite itself, or by a [VFS | custom VFS implementation].

** SQLite interprets the following three query parameters:
**
** <ul>
**   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
**     a VFS object that provides the operating system interface that should
**     be used to access the database file on disk. ^If this option is set to
**     an empty string the default VFS object is used. ^Specifying an unknown
**     VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is







|
|




>
|







2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
** present, is ignored.
**
** ^SQLite uses the path component of the URI as the name of the disk file
** which contains the database. ^If the path begins with a '/' character, 
** then it is interpreted as an absolute path. ^If the path does not begin 
** with a '/' (meaning that the authority section is omitted from the URI)
** then the path is interpreted as a relative path. 
** ^(On windows, the first component of an absolute path 
** is a drive specification (e.g. "C:").)^
**
** [[core URI query parameters]]
** The query component of a URI may contain parameters that are interpreted
** either by SQLite itself, or by a [VFS | custom VFS implementation].
** SQLite and its built-in [VFSes] interpret the
** following query parameters:
**
** <ul>
**   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
**     a VFS object that provides the operating system interface that should
**     be used to access the database file on disk. ^If this option is set to
**     an empty string the default VFS object is used. ^Specifying an unknown
**     VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
**     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
**     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
**     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
**     a URI filename, its value overrides any behavior requested by setting
**     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
**
**  <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
**     "1") or "false" (or "off" or "no" or "0") to indicate that the
**     [powersafe overwrite] property does or does not apply to the
**     storage media on which the database file resides.  ^The psow query
**     parameter only works for the built-in unix and Windows VFSes.
**
**  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
**     which if set disables file locking in rollback journal modes.  This
**     is useful for accessing a database on a filesystem that does not
**     support locking.  Caution:  Database corruption might result if two
**     or more processes write to the same database and any one of those
**     processes uses nolock=1.







|
<

|
<







2942
2943
2944
2945
2946
2947
2948
2949

2950
2951

2952
2953
2954
2955
2956
2957
2958
**     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
**     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
**     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
**     a URI filename, its value overrides any behavior requested by setting
**     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
**
**  <li> <b>psow</b>: ^The psow parameter indicates whether or not the

**     [powersafe overwrite] property does or does not apply to the
**     storage media on which the database file resides.

**
**  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
**     which if set disables file locking in rollback journal modes.  This
**     is useful for accessing a database on a filesystem that does not
**     support locking.  Caution:  Database corruption might result if two
**     or more processes write to the same database and any one of those
**     processes uses nolock=1.
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated.  If any NUL characters occur at byte offsets less than 
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs.  The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it.  ^The destructor is called
** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
** to specify the encoding of the text in the third parameter.  If
** the sixth argument to sqlite3_bind_text64() is not how of the
** allowed values shown above, or if the text encoding is different
** from the encoding specified by the sixth parameter, then the behavior
** is undefined.
**
** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
** (just an integer to hold its size) while it is being processed.







|
|

|
<










|







3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549

3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated.  If any NUL characters occur at byte offsets less than 
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs.  The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to the BLOB and string binding interfaces
** is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it.  ^The destructor is called
** to dispose of the BLOB or string even if the call to bind API fails.

** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
** to specify the encoding of the text in the third parameter.  If
** the sixth argument to sqlite3_bind_text64() is not one of the
** allowed values shown above, or if the text encoding is different
** from the encoding specified by the sixth parameter, then the behavior
** is undefined.
**
** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
** (just an integer to hold its size) while it is being processed.
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286

/*
** CAPI3REF: Text Encodings
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
*/
#define SQLITE_UTF8           1
#define SQLITE_UTF16LE        2
#define SQLITE_UTF16BE        3
#define SQLITE_UTF16          4    /* Use native byte order */
#define SQLITE_ANY            5    /* Deprecated */
#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */

/*
** CAPI3REF: Function Flags
**







|
|
|







4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305

/*
** CAPI3REF: Text Encodings
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
*/
#define SQLITE_UTF8           1    /* IMP: R-37514-35566 */
#define SQLITE_UTF16LE        2    /* IMP: R-03371-37637 */
#define SQLITE_UTF16BE        3    /* IMP: R-51971-34154 */
#define SQLITE_UTF16          4    /* Use native byte order */
#define SQLITE_ANY            5    /* Deprecated */
#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */

/*
** CAPI3REF: Function Flags
**
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
** of the application-defined function to be the 64-bit signed integer
** value given in the 2nd argument.
**
** ^The sqlite3_result_null() interface sets the return value
** of the application-defined function to be NULL.
**
** ^The sqlite3_result_text(), sqlite3_result_text16(),
** sqlite3_result_text16le(), and sqlite3_result_text16be()
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^The sqlite3_result_text64() interface sets the return value of an
** application-defined function to be a text string in an encoding
** specified by the fifth (and last) parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].







|







4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
** of the application-defined function to be the 64-bit signed integer
** value given in the 2nd argument.
**
** ^The sqlite3_result_null() interface sets the return value
** of the application-defined function to be NULL.
**
** ^The sqlite3_result_text(), sqlite3_result_text16(),
** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^The sqlite3_result_text64() interface sets the return value of an
** application-defined function to be a text string in an encoding
** specified by the fifth (and last) parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781




5782
5783





5784















5785
5786
5787
5788
5789

5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
** in other words, the same BLOB that would be selected by:
**
** <pre>
**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**
** ^If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. ^If it is zero, the BLOB is opened for read access.
** ^It is not possible to open a column that is part of an index or primary 
** key for writing. ^If [foreign key constraints] are enabled, it is 
** not possible to open a column that is part of a [child key] for writing.
**
** ^Note that the database name is not the filename that contains
** the database but rather the symbolic name of the database that
** appears after the AS keyword when the database is connected using [ATTACH].
** ^For the main database file, the database name is "main".
** ^For TEMP tables, the database name is "temp".
**




** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set





** to be a null pointer.)^















** ^This function sets the [database connection] error code and message
** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
** functions. ^Note that the *ppBlob variable is always initialized in a
** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
** regardless of the success or failure of this routine.

**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
** ^(Changes written into a BLOB prior to the BLOB expiring are not
** rolled back by the expiration of the BLOB.  Such changes will eventually
** commit if the transaction continues to completion.)^
**
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  ^The size of a blob may not be changed by this
** interface.  Use the [UPDATE] SQL command to change the size of a
** blob.
**
** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
** table.  Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
** this interface.
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
*/
SQLITE_API int sqlite3_blob_open(
  sqlite3*,
  const char *zDb,








<
<
<
<
<
<
|
|
|
|
|

>
>
>
>
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
<
>

















<
<
<

|
|
<







5781
5782
5783
5784
5785
5786
5787
5788






5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823



5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841



5842
5843
5844

5845
5846
5847
5848
5849
5850
5851
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
** in other words, the same BLOB that would be selected by:
**
** <pre>
**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**






** ^(Parameter zDb is not the filename that contains the database, but 
** rather the symbolic name of the database. For attached databases, this is
** the name that appears after the AS keyword in the [ATTACH] statement.
** For the main database file, the database name is "main". For TEMP
** tables, the database name is "temp".)^
**
** ^If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. ^If the flags parameter is zero, the BLOB is opened for
** read-only access.
**
** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
** in *ppBlob. Otherwise an [error code] is returned and, unless the error
** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
** the API is not misused, it is always safe to call [sqlite3_blob_close()] 
** on *ppBlob after this function it returns.
**
** This function fails with SQLITE_ERROR if any of the following are true:
** <ul>
**   <li> ^(Database zDb does not exist)^, 
**   <li> ^(Table zTable does not exist within database zDb)^, 
**   <li> ^(Table zTable is a WITHOUT ROWID table)^, 
**   <li> ^(Column zColumn does not exist)^,
**   <li> ^(Row iRow is not present in the table)^,
**   <li> ^(The specified column of row iRow contains a value that is not
**         a TEXT or BLOB value)^,
**   <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE 
**         constraint and the blob is being opened for read/write access)^,
**   <li> ^([foreign key constraints | Foreign key constraints] are enabled, 
**         column zColumn is part of a [child key] definition and the blob is
**         being opened for read/write access)^.
** </ul>
**
** ^Unless it returns SQLITE_MISUSE, this function sets the 
** [database connection] error code and message accessible via 
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 



**
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
** ^(Changes written into a BLOB prior to the BLOB expiring are not
** rolled back by the expiration of the BLOB.  Such changes will eventually
** commit if the transaction continues to completion.)^
**
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  ^The size of a blob may not be changed by this
** interface.  Use the [UPDATE] SQL command to change the size of a
** blob.
**



** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function may be used to create a 
** zero-filled blob to read or write using the incremental-blob interface.

**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
*/
SQLITE_API int sqlite3_blob_open(
  sqlite3*,
  const char *zDb,
5848
5849
5850
5851
5852
5853
5854
5855


5856


5857

5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872


5873
5874
5875
5876
5877
5878
5879
** ^This function sets the database handle error code and message.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);

/*
** CAPI3REF: Close A BLOB Handle
**
** ^Closes an open [BLOB handle].


**


** ^Closing a BLOB shall cause the current transaction to commit

** if there are no other BLOBs, no pending prepared statements, and the
** database connection is in [autocommit mode].
** ^If any writes were made to the BLOB, they might be held in cache
** until the close operation if they will fit.
**
** ^(Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
** at the time when the BLOB is closed.  Any errors that occur during
** closing are reported as a non-zero return value.)^
**
** ^(The BLOB is closed unconditionally.  Even if this routine returns
** an error code, the BLOB is still closed.)^
**
** ^Calling this routine with a null pointer (such as would be returned
** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.


*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *);

/*
** CAPI3REF: Return The Size Of An Open BLOB
**
** ^Returns the size in bytes of the BLOB accessible via the 







|
>
>

>
>
|
>
|
<
<
<

|
<
<
|
<
<
<
<
|
|
>
>







5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894



5895
5896


5897




5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
** ^This function sets the database handle error code and message.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);

/*
** CAPI3REF: Close A BLOB Handle
**
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
** unconditionally.  Even if this routine returns an error code, the 
** handle is still closed.)^
**
** ^If the blob handle being closed was opened for read-write access, and if
** the database is in auto-commit mode and there are no other open read-write
** blob handles or active write statements, the current transaction is
** committed. ^If an error occurs while committing the transaction, an error
** code is returned and the transaction rolled back.



**
** Calling this function with an argument that is not a NULL pointer or an


** open blob handle results in undefined behaviour. ^Calling this routine 




** with a null pointer (such as would be returned by a failed call to 
** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
** is passed a valid open blob handle, the values returned by the 
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *);

/*
** CAPI3REF: Return The Size Of An Open BLOB
**
** ^Returns the size in bytes of the BLOB accessible via the 
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924






5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936

5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
** See also: [sqlite3_blob_write()].
*/
SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);

/*
** CAPI3REF: Write Data Into A BLOB Incrementally
**
** ^This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. ^N bytes of data are copied from the buffer Z
** into the open BLOB, starting at offset iOffset.






**
** ^If the [BLOB handle] passed as the first argument was not opened for
** writing (the flags parameter to [sqlite3_blob_open()] was zero),
** this function returns [SQLITE_READONLY].
**
** ^This function may only modify the contents of the BLOB; it is
** not possible to increase the size of a BLOB using this API.
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written.  ^If N is
** less than zero [SQLITE_ERROR] is returned and no data is written.
** The size of the BLOB (and hence the maximum value of N+iOffset)
** can be determined using the [sqlite3_blob_bytes()] interface.

**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
** before the [BLOB handle] expired are not rolled back by the
** expiration of the handle, though of course those changes might
** have been overwritten by the statement that expired the BLOB handle
** or by other independent statements.
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an  [error code] or an [extended error code] is returned.)^
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()].  Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
**
** See also: [sqlite3_blob_read()].
*/







|
|
|
>
>
>
>
>
>





|


|
<
|
|
>








<
<
<







5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968

5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979



5980
5981
5982
5983
5984
5985
5986
** See also: [sqlite3_blob_write()].
*/
SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);

/*
** CAPI3REF: Write Data Into A BLOB Incrementally
**
** ^(This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. N bytes of data are copied from the buffer Z
** into the open BLOB, starting at offset iOffset.)^
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an  [error code] or an [extended error code] is returned.)^
** ^Unless SQLITE_MISUSE is returned, this function sets the 
** [database connection] error code and message accessible via 
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
**
** ^If the [BLOB handle] passed as the first argument was not opened for
** writing (the flags parameter to [sqlite3_blob_open()] was zero),
** this function returns [SQLITE_READONLY].
**
** This function may only modify the contents of the BLOB; it is
** not possible to increase the size of a BLOB using this API.
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written. The size of the 

** BLOB (and hence the maximum value of N+iOffset) can be determined 
** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less 
** than zero [SQLITE_ERROR] is returned and no data is written.
**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
** before the [BLOB handle] expired are not rolled back by the
** expiration of the handle, though of course those changes might
** have been overwritten by the statement that expired the BLOB handle
** or by other independent statements.
**



** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()].  Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
**
** See also: [sqlite3_blob_read()].
*/
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039

6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091

6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
** use by SQLite, code that links against SQLite is
** permitted to use any of these routines.
**
** The SQLite source code contains multiple implementations
** of these mutex routines.  An appropriate implementation
** is selected automatically at compile-time.  ^(The following
** implementations are available in the SQLite core:
**
** <ul>
** <li>   SQLITE_MUTEX_PTHREADS
** <li>   SQLITE_MUTEX_W32
** <li>   SQLITE_MUTEX_NOOP
** </ul>)^
**
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
** and Windows.
**
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().)^
**
** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^If it returns NULL
** that means that a mutex could not be allocated.  ^SQLite
** will unwind its stack and return an error.  ^(The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2

** </ul>)^
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
** cause sqlite3_mutex_alloc() to create
** a new mutex.  ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  ^SQLite will only request a recursive mutex in
** cases where it really needs one.  ^If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
** a pointer to a static preexisting mutex.  ^Six static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  ^But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
**
** ^The sqlite3_mutex_free() routine deallocates a previously
** allocated dynamic mutex.  ^SQLite is careful to deallocate every
** dynamic mutex that it allocates.  The dynamic mutexes must not be in
** use when they are deallocated.  Attempting to deallocate a static
** mutex results in undefined behavior.  ^SQLite never deallocates
** a static mutex.
**
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  ^If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
** upon successful entry.  ^(Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
** In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.)^  ^(If the same thread tries to enter any other
** kind of mutex more than once, the behavior is undefined.
** SQLite will never exhibit
** such behavior in its own use of mutexes.)^
**
** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
** will always return SQLITE_BUSY.  The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^

**
** ^The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.   ^(The behavior
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated.  SQLite will
** never do either.)^
**
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
** behave as no-ops.
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);

/*
** CAPI3REF: Mutex Methods Object
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
**
** Usually, the default mutex implementations provided by SQLite are
** sufficient, however the user has the option of substituting a custom
** implementation for specialized deployments or systems for which SQLite
** does not provide a suitable implementation. In this case, the user
** creates and populates an instance of this structure to pass
** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
** Additionally, an instance of this structure can be used as an
** output variable when querying the system for the current mutex
** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
**
** ^The xMutexInit method defined by this structure is invoked as







|






|

|

|



|





|


|
|
|
|












>
|







|
|





|








|




<
<
|
|
<







|

|
|
<
<



|
|
>


|

|
<




















|

|







6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101


6102
6103

6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114


6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125

6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
** use by SQLite, code that links against SQLite is
** permitted to use any of these routines.
**
** The SQLite source code contains multiple implementations
** of these mutex routines.  An appropriate implementation
** is selected automatically at compile-time.  The following
** implementations are available in the SQLite core:
**
** <ul>
** <li>   SQLITE_MUTEX_PTHREADS
** <li>   SQLITE_MUTEX_W32
** <li>   SQLITE_MUTEX_NOOP
** </ul>
**
** The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
** a single-threaded application.  The SQLITE_MUTEX_PTHREADS and
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
** and Windows.
**
** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().
**
** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
** routine returns NULL if it is unable to allocate the requested
** mutex.  The argument to sqlite3_mutex_alloc() must one of these
** integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2
** <li>  SQLITE_MUTEX_STATIC_APP3
** </ul>
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
** cause sqlite3_mutex_alloc() to create
** a new mutex.  ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  SQLite will only request a recursive mutex in
** cases where it really needs one.  If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
** a pointer to a static preexisting mutex.  ^Nine static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  ^For the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
**
** ^The sqlite3_mutex_free() routine deallocates a previously


** allocated dynamic mutex.  Attempting to deallocate a static
** mutex results in undefined behavior.

**
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  ^If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
** upon successful entry.  ^(Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
** In such cases, the
** mutex must be exited an equal number of times before another thread
** can enter.)^  If the same thread tries to enter any mutex other
** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.


**
** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
** will always return SQLITE_BUSY. The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable 
** behavior.)^
**
** ^The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.   The behavior
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated.

**
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
** behave as no-ops.
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);

/*
** CAPI3REF: Mutex Methods Object
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
**
** Usually, the default mutex implementations provided by SQLite are
** sufficient, however the application has the option of substituting a custom
** implementation for specialized deployments or systems for which SQLite
** does not provide a suitable implementation. In this case, the application
** creates and populates an instance of this structure to pass
** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
** Additionally, an instance of this structure can be used as an
** output variable when querying the system for the current mutex
** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
**
** ^The xMutexInit method defined by this structure is invoked as
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe.  ^It must be harmless to
** invoke xMutexInit() multiple times within the same process and without
** intervening calls to xMutexEnd().  Second and subsequent calls to
** xMutexInit() must be no-ops.
**
** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
** and its associates).  ^Similarly, xMutexAlloc() must not use SQLite memory
** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
** memory allocation for a fast or recursive mutex.
**
** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
** called, but only if the prior call to xMutexInit returned SQLITE_OK.
** If xMutexInit fails in any way, it is expected to clean up after itself
** prior to returning.







|




|
|







6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe.  It must be harmless to
** invoke xMutexInit() multiple times within the same process and without
** intervening calls to xMutexEnd().  Second and subsequent calls to
** xMutexInit() must be no-ops.
**
** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
** and its associates).  Similarly, xMutexAlloc() must not use SQLite memory
** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
** memory allocation for a fast or recursive mutex.
**
** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
** called, but only if the prior call to xMutexInit returned SQLITE_OK.
** If xMutexInit fails in any way, it is expected to clean up after itself
** prior to returning.
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
  int (*xMutexNotheld)(sqlite3_mutex *);
};

/*
** CAPI3REF: Mutex Verification Routines
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
** are intended for use inside assert() statements.  ^The SQLite core
** never uses these routines except inside an assert() and applications
** are advised to follow the lead of the core.  ^The SQLite core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag.  ^External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
** ^These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** ^The implementation is not required to provide versions of these
** routines that actually work. If the implementation does not provide working
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
** the routine should return 1.   This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist.  But
** the reason the mutex does not exist is because the build is not
** using mutexes.  And we do not want the assert() containing the
** call to sqlite3_mutex_held() to fail, so a non-zero return is
** the appropriate thing to do.  ^The sqlite3_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif








|

|

|



|


|




|





|







6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
  int (*xMutexNotheld)(sqlite3_mutex *);
};

/*
** CAPI3REF: Mutex Verification Routines
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
** are intended for use inside assert() statements.  The SQLite core
** never uses these routines except inside an assert() and applications
** are advised to follow the lead of the core.  The SQLite core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag.  External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
** These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** The implementation is not required to provide versions of these
** routines that actually work. If the implementation does not provide working
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
** If the argument to sqlite3_mutex_held() is a NULL pointer then
** the routine should return 1.   This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist.  But
** the reason the mutex does not exist is because the build is not
** using mutexes.  And we do not want the assert() containing the
** call to sqlite3_mutex_held() to fail, so a non-zero return is
** the appropriate thing to do.  The sqlite3_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif

6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
#define SQLITE_TESTCTRL_ASSERT                  12
#define SQLITE_TESTCTRL_ALWAYS                  13
#define SQLITE_TESTCTRL_RESERVE                 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS           15
#define SQLITE_TESTCTRL_ISKEYWORD               16
#define SQLITE_TESTCTRL_SCRATCHMALLOC           17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
#define SQLITE_TESTCTRL_EXPLAIN_STMT            19
#define SQLITE_TESTCTRL_NEVER_CORRUPT           20
#define SQLITE_TESTCTRL_VDBE_COVERAGE           21
#define SQLITE_TESTCTRL_BYTEORDER               22
#define SQLITE_TESTCTRL_ISINIT                  23
#define SQLITE_TESTCTRL_SORTER_MMAP             24
#define SQLITE_TESTCTRL_LAST                    24








|







6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
#define SQLITE_TESTCTRL_ASSERT                  12
#define SQLITE_TESTCTRL_ALWAYS                  13
#define SQLITE_TESTCTRL_RESERVE                 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS           15
#define SQLITE_TESTCTRL_ISKEYWORD               16
#define SQLITE_TESTCTRL_SCRATCHMALLOC           17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
#define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
#define SQLITE_TESTCTRL_NEVER_CORRUPT           20
#define SQLITE_TESTCTRL_VDBE_COVERAGE           21
#define SQLITE_TESTCTRL_BYTEORDER               22
#define SQLITE_TESTCTRL_ISINIT                  23
#define SQLITE_TESTCTRL_SORTER_MMAP             24
#define SQLITE_TESTCTRL_LAST                    24

6940
6941
6942
6943
6944
6945
6946




6947
6948
6949
6950
6951
6952
6953
** an [ATTACH] statement for an attached database.
** ^The S and M arguments passed to 
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
** and database name of the source database, respectively.
** ^The source and destination [database connections] (parameters S and D)
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.




**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
** ^The error code and message for the failed call to sqlite3_backup_init()
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
** [sqlite3_errmsg16()] functions.







>
>
>
>







6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
** an [ATTACH] statement for an attached database.
** ^The S and M arguments passed to 
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
** and database name of the source database, respectively.
** ^The source and destination [database connections] (parameters S and D)
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
** there is already a read or read-write transaction open on the 
** destination database.
**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
** ^The error code and message for the failed call to sqlite3_backup_init()
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
** [sqlite3_errmsg16()] functions.
7533
7534
7535
7536
7537
7538
7539




























































































7540
7541
7542
7543
7544
7545
7546
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5































































































/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5

/*
** CAPI3REF: Prepared Statement Scan Status Opcodes
** KEYWORDS: {scanstatus options}
**
** The following constants can be used for the T parameter to the
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface.  Each constant designates a
** different metric for sqlite3_stmt_scanstatus() to return.
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of rows examined by all iterations of the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
** <dd>^The "double" variable pointed to by the T parameter will be set to the
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop.  If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
** product of this value for all prior loops with the same SELECTID will
** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
** <dd>^The "const char *" variable pointed to by the T parameter will be set to 
** a zero-terminated UTF-8 string containing the name of the index or table used
** for the X-th loop.
**
** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
** <dd>^The "const char *" variable pointed to by the T parameter will be set to 
** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description
** for the X-th loop.
**
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
** <dd>^The "int" variable pointed to by the T parameter will be set to the
** "select-id" for the X-th loop.  The select-id identifies which query or
** subquery the loop is part of.  The main query has a select-id of zero.
** The select-id is the same value as is output in the first column
** of an [EXPLAIN QUERY PLAN] query.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP    0
#define SQLITE_SCANSTAT_NVISIT   1
#define SQLITE_SCANSTAT_EST      2
#define SQLITE_SCANSTAT_NAME     3
#define SQLITE_SCANSTAT_EXPLAIN  4
#define SQLITE_SCANSTAT_SELECTID 5

/*
** CAPI3REF: Prepared Statement Scan Status
**
** Return status data for a single loop within query pStmt.
**
** The "iScanStatusOp" parameter determines which status information to return.
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of
** this interface is undefined.
** ^The requested measurement is written into a variable pointed to by
** the "pOut" parameter.
** Parameter "idx" identifies the specific loop to retrieve statistics for.
** Loops are numbered starting from zero. ^If idx is out of range - less than
** zero or greater than or equal to the total number of loops used to implement
** the statement - a non-zero value is returned and the variable that pOut
** points to is unchanged.
**
** ^Statistics might not be available for all loops in all statements. ^In cases
** where there exist loops with no available statistics, this function behaves
** as if the loop did not exist - it returns non-zero and leave the variable
** that pOut points to unchanged.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
  int idx,                  /* Index of loop to report on */
  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
  void *pOut                /* Result written here */
);     

/*
** CAPI3REF: Zero Scan-Status Counters
**
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);


/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958

/*
** A macro to hint to the compiler that a function should not be
** inlined.
*/
#if defined(__GNUC__)
#  define SQLITE_NOINLINE  __attribute__((noinline))
#elif defined(_MSC_VER)
#  define SQLITE_NOINLINE  __declspec(noinline)
#else
#  define SQLITE_NOINLINE
#endif

/*
** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.







|







8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082

/*
** A macro to hint to the compiler that a function should not be
** inlined.
*/
#if defined(__GNUC__)
#  define SQLITE_NOINLINE  __attribute__((noinline))
#elif defined(_MSC_VER) && _MSC_VER>=1310
#  define SQLITE_NOINLINE  __declspec(noinline)
#else
#  define SQLITE_NOINLINE
#endif

/*
** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
7978
7979
7980
7981
7982
7983
7984

7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
*/
#ifndef SQLITE_POWERSAFE_OVERWRITE
# define SQLITE_POWERSAFE_OVERWRITE 1
#endif

/*

** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
** It determines whether or not the features related to 
** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
** be overridden at runtime using the sqlite3_config() API.
*/
#if !defined(SQLITE_DEFAULT_MEMSTATUS)
# define SQLITE_DEFAULT_MEMSTATUS 1
#endif

/*
** Exactly one of the following macros must be defined in order to







>
|
<
|
<







8102
8103
8104
8105
8106
8107
8108
8109
8110

8111

8112
8113
8114
8115
8116
8117
8118
** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
*/
#ifndef SQLITE_POWERSAFE_OVERWRITE
# define SQLITE_POWERSAFE_OVERWRITE 1
#endif

/*
** EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by
** default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in

** which case memory allocation statistics are disabled by default.

*/
#if !defined(SQLITE_DEFAULT_MEMSTATUS)
# define SQLITE_DEFAULT_MEMSTATUS 1
#endif

/*
** Exactly one of the following macros must be defined in order to
8517
8518
8519
8520
8521
8522
8523





8524
8525
8526
8527
8528
8529
8530

/*
** Macros to compute minimum and maximum of two numbers.
*/
#define MIN(A,B) ((A)<(B)?(A):(B))
#define MAX(A,B) ((A)>(B)?(A):(B))






/*
** Check to see if this machine uses EBCDIC.  (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
#if 'A' == '\301'
# define SQLITE_EBCDIC 1
#else







>
>
>
>
>







8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658

/*
** Macros to compute minimum and maximum of two numbers.
*/
#define MIN(A,B) ((A)<(B)?(A):(B))
#define MAX(A,B) ((A)>(B)?(A):(B))

/*
** Swap two objects of type TYPE.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Check to see if this machine uses EBCDIC.  (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
#if 'A' == '\301'
# define SQLITE_EBCDIC 1
#else
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620

/*
** Estimated quantities used for query planning are stored as 16-bit
** logarithms.  For quantity X, the value stored is 10*log2(X).  This
** gives a possible range of values of approximately 1.0e986 to 1e-986.
** But the allowed values are "grainy".  Not every value is representable.
** For example, quantities 16 and 17 are both represented by a LogEst
** of 40.  However, since LogEst quantaties are suppose to be estimates,
** not exact values, this imprecision is not a problem.
**
** "LogEst" is short for "Logarithmic Estimate".
**
** Examples:
**      1 -> 0              20 -> 43          10000 -> 132
**      2 -> 10             25 -> 46          25000 -> 146







|







8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748

/*
** Estimated quantities used for query planning are stored as 16-bit
** logarithms.  For quantity X, the value stored is 10*log2(X).  This
** gives a possible range of values of approximately 1.0e986 to 1e-986.
** But the allowed values are "grainy".  Not every value is representable.
** For example, quantities 16 and 17 are both represented by a LogEst
** of 40.  However, since LogEst quantities are suppose to be estimates,
** not exact values, this imprecision is not a problem.
**
** "LogEst" is short for "Logarithmic Estimate".
**
** Examples:
**      1 -> 0              20 -> 43          10000 -> 132
**      2 -> 10             25 -> 46          25000 -> 146
8754
8755
8756
8757
8758
8759
8760










8761
8762
8763
8764
8765
8766
8767
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3_OR_STAT4
# undef SQLITE_ENABLE_STAT3_OR_STAT4
#endif











/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle. 
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler







>
>
>
>
>
>
>
>
>
>







8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3_OR_STAT4
# undef SQLITE_ENABLE_STAT3_OR_STAT4
#endif

/*
** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
** the Select query generator tracing logic is turned on.
*/
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE)
# define SELECTTRACE_ENABLED 1
#else
# define SELECTTRACE_ENABLED 0
#endif

/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle. 
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
8893
8894
8895
8896
8897
8898
8899

8900
8901
8902
8903
8904
8905
8906
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;

typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;
typedef struct UnpackedRecord UnpackedRecord;
typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;







>







9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TreeView TreeView;
typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;
typedef struct UnpackedRecord UnpackedRecord;
typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
#endif
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);







|







9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
#endif
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int);
SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
*/
#define BTREE_INTKEY     1    /* Table has only 64-bit signed integer keys */
#define BTREE_BLOBKEY    2    /* Table has keys only - no data */

SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);

SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);

SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);

/*







|







9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
*/
#define BTREE_INTKEY     1    /* Table has only 64-bit signed integer keys */
#define BTREE_BLOBKEY    2    /* Table has keys only - no data */

SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int);

SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);

SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);

/*
9108
9109
9110
9111
9112
9113
9114

9115
9116
9117
9118
9119
9120
9121

SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *);
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt);


#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
#endif

#ifndef SQLITE_OMIT_BTREECOUNT
SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);







>







9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261

SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *);
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt);
SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void);

#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
#endif

#ifndef SQLITE_OMIT_BTREECOUNT
SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
9650
9651
9652
9653
9654
9655
9656






9657
9658
9659
9660
9661
9662
9663
# define VdbeCoverage(v)
# define VdbeCoverageIf(v,x)
# define VdbeCoverageAlwaysTaken(v)
# define VdbeCoverageNeverTaken(v)
# define VDBE_OFFSET_LINENO(x) 0
#endif







#endif

/************** End of vdbe.h ************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include pager.h in the middle of sqliteInt.h *****************/
/************** Begin file pager.h *******************************************/
/*







>
>
>
>
>
>







9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
# define VdbeCoverage(v)
# define VdbeCoverageIf(v,x)
# define VdbeCoverageAlwaysTaken(v)
# define VdbeCoverageNeverTaken(v)
# define VDBE_OFFSET_LINENO(x) 0
#endif

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*);
#else
# define sqlite3VdbeScanStatus(a,b,c,d,e)
#endif

#endif

/************** End of vdbe.h ************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include pager.h in the middle of sqliteInt.h *****************/
/************** Begin file pager.h *******************************************/
/*
9846
9847
9848
9849
9850
9851
9852


9853
9854
9855
9856
9857
9858
9859
SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *);
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);

/* Functions used to truncate the database file. */
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);



#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
#endif

/* Functions to support testing and debugging. */
#if !defined(NDEBUG) || defined(SQLITE_TEST)
SQLITE_PRIVATE   Pgno sqlite3PagerPagenumber(DbPage*);







>
>







9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *);
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);

/* Functions used to truncate the database file. */
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);

SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);

#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
#endif

/* Functions to support testing and debugging. */
#if !defined(NDEBUG) || defined(SQLITE_TEST)
SQLITE_PRIVATE   Pgno sqlite3PagerPagenumber(DbPage*);
10033
10034
10035
10036
10037
10038
10039




10040
10041
10042
10043
10044
10045
10046

#ifdef SQLITE_TEST
SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*);
#endif

SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);





#endif /* _PCACHE_H_ */

/************** End of pcache.h **********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/

/************** Include os.h in the middle of sqliteInt.h ********************/
/************** Begin file os.h **********************************************/







>
>
>
>







10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198

#ifdef SQLITE_TEST
SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*);
#endif

SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);

/* Return the header size */
SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);

#endif /* _PCACHE_H_ */

/************** End of pcache.h **********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/

/************** Include os.h in the middle of sqliteInt.h ********************/
/************** Begin file os.h **********************************************/
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
/*                not used    0x0010   // Was: SQLITE_IdxRealAsInt */
#define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
#define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
#define SQLITE_Transitive     0x0200   /* Transitive constraints */
#define SQLITE_OmitNoopJoin   0x0400   /* Omit unused tables in joins */
#define SQLITE_Stat3          0x0800   /* Use the SQLITE_STAT3 table */
#define SQLITE_AllOpts        0xffff   /* All optimizations */

/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
#define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)







|







10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
/*                not used    0x0010   // Was: SQLITE_IdxRealAsInt */
#define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
#define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
#define SQLITE_Transitive     0x0200   /* Transitive constraints */
#define SQLITE_OmitNoopJoin   0x0400   /* Omit unused tables in joins */
#define SQLITE_Stat34         0x0800   /* Use STAT3 or STAT4 data */
#define SQLITE_AllOpts        0xffff   /* All optimizations */

/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
#define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
11301
11302
11303
11304
11305
11306
11307

11308
11309
11310
11311
11312


11313
11314
11315
11316
11317
11318
11319
  u16 nColumn;             /* Number of columns stored in the index */
  u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  unsigned idxType:2;      /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
  unsigned bUnordered:1;   /* Use this index for == or IN queries only */
  unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
  unsigned isResized:1;    /* True if resizeIndexObject() has been called */
  unsigned isCovering:1;   /* True if this is a covering index */

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  int nSample;             /* Number of elements in aSample[] */
  int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
  tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */


#endif
};

/*
** Allowed values for Index.idxType
*/
#define SQLITE_IDXTYPE_APPDEF      0   /* Created using CREATE INDEX */







>





>
>







11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
  u16 nColumn;             /* Number of columns stored in the index */
  u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  unsigned idxType:2;      /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
  unsigned bUnordered:1;   /* Use this index for == or IN queries only */
  unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
  unsigned isResized:1;    /* True if resizeIndexObject() has been called */
  unsigned isCovering:1;   /* True if this is a covering index */
  unsigned noSkipScan:1;   /* Do not try to use skip-scan if true */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  int nSample;             /* Number of elements in aSample[] */
  int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
  tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */
  tRowcnt *aiRowEst;       /* Non-logarithmic stat1 data for this index */
  tRowcnt nRowEst0;        /* Non-logarithmic number of rows in the index */
#endif
};

/*
** Allowed values for Index.idxType
*/
#define SQLITE_IDXTYPE_APPDEF      0   /* Created using CREATE INDEX */
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517

#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old
                         ** EP_Unlikely:  1000 times likelihood */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1). */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 op2;                /* TK_REGISTER: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */







|







11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672

#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old
                         ** EP_Unlikely:  134217728 times likelihood */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1). */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 op2;                /* TK_REGISTER: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
#define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
#define WHERE_ORDERBY_MAX      0x0002 /* ORDER BY processing for max() func */
#define WHERE_ONEPASS_DESIRED  0x0004 /* Want to do one-pass UPDATE/DELETE */
#define WHERE_DUPLICATES_OK    0x0008 /* Ok to return a row more than once */
#define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
#define WHERE_FORCE_TABLE      0x0020 /* Do not use an index-only search */
#define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
#define WHERE_AND_ONLY         0x0080 /* Don't use indices for OR terms */
#define WHERE_GROUPBY          0x0100 /* pOrderBy is really a GROUP BY */
#define WHERE_DISTINCTBY       0x0200 /* pOrderby is really a DISTINCT clause */
#define WHERE_WANT_DISTINCT    0x0400 /* All output needs to be distinct */
#define WHERE_SORTBYGROUP      0x0800 /* Support sqlite3WhereIsSorted() */
#define WHERE_REOPEN_IDX       0x1000 /* Try to use OP_ReopenIdx */

/* Allowed return values from sqlite3WhereIsDistinct()







|







11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
#define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
#define WHERE_ORDERBY_MAX      0x0002 /* ORDER BY processing for max() func */
#define WHERE_ONEPASS_DESIRED  0x0004 /* Want to do one-pass UPDATE/DELETE */
#define WHERE_DUPLICATES_OK    0x0008 /* Ok to return a row more than once */
#define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
#define WHERE_FORCE_TABLE      0x0020 /* Do not use an index-only search */
#define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
                          /*   0x0080 // not currently used */
#define WHERE_GROUPBY          0x0100 /* pOrderBy is really a GROUP BY */
#define WHERE_DISTINCTBY       0x0200 /* pOrderby is really a DISTINCT clause */
#define WHERE_WANT_DISTINCT    0x0400 /* All output needs to be distinct */
#define WHERE_SORTBYGROUP      0x0800 /* Support sqlite3WhereIsSorted() */
#define WHERE_REOPEN_IDX       0x1000 /* Try to use OP_ReopenIdx */

/* Allowed return values from sqlite3WhereIsDistinct()
11821
11822
11823
11824
11825
11826
11827



11828
11829
11830
11831
11832
11833
11834
** sequences for the ORDER BY clause.
*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  u16 selFlags;          /* Various SF_* values */
  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */



  int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
  u64 nSelectRow;        /* Estimated number of result rows */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */







>
>
>







11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
** sequences for the ORDER BY clause.
*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  u16 selFlags;          /* Various SF_* values */
  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
#if SELECTTRACE_ENABLED
  char zSelName[12];     /* Symbolic name of this SELECT use for debugging */
#endif
  int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
  u64 nSelectRow;        /* Estimated number of result rows */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
12079
12080
12081
12082
12083
12084
12085




12086
12087
12088
12089
12090
12091
12092
  Token constraintName;/* Name of the constraint currently being parsed */
  yDbMask writeMask;   /* Start a write transaction on these databases */
  yDbMask cookieMask;  /* Bitmask of schema verified databases */
  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  int regRoot;         /* Register holding root page number for new objects */
  int nMaxArg;         /* Max args passed to user function by sub-program */




#ifndef SQLITE_OMIT_SHARED_CACHE
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */

  /* Information used while coding trigger programs. */







>
>
>
>







12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
  Token constraintName;/* Name of the constraint currently being parsed */
  yDbMask writeMask;   /* Start a write transaction on these databases */
  yDbMask cookieMask;  /* Bitmask of schema verified databases */
  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  int regRoot;         /* Register holding root page number for new objects */
  int nMaxArg;         /* Max args passed to user function by sub-program */
#if SELECTTRACE_ENABLED
  int nSelect;         /* Number of SELECT statements seen */
  int nSelectIndent;   /* How far to indent SELECTTRACE() output */
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */

  /* Information used while coding trigger programs. */
12158
12159
12160
12161
12162
12163
12164

12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P5 value in various opcodes.
*/
#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */

#define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND        0x08    /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
#define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
#define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */

/*







>




<







12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331

12332
12333
12334
12335
12336
12337
12338
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P5 value in various opcodes.
*/
#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
#define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
#define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND        0x08    /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */

#define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
#define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */

/*
12388
12389
12390
12391
12392
12393
12394

12395
12396
12397

12398
12399
12400
12401
12402
12403
12404
*/
struct Walker {
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
  Parse *pParse;                            /* Parser context.  */
  int walkerDepth;                          /* Number of subqueries */

  union {                                   /* Extra data for callback */
    NameContext *pNC;                          /* Naming context */
    int i;                                     /* Integer value */

    SrcList *pSrcList;                         /* FROM clause */
    struct SrcCount *pSrcCount;                /* Counting column references */
  } u;
};

/* Forward declarations */
SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);







>


|
>







12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
*/
struct Walker {
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
  Parse *pParse;                            /* Parser context.  */
  int walkerDepth;                          /* Number of subqueries */
  u8 eCode;                                 /* A small processing code */
  union {                                   /* Extra data for callback */
    NameContext *pNC;                          /* Naming context */
    int n;                                     /* A counter */
    int iCur;                                  /* A cursor number */
    SrcList *pSrcList;                         /* FROM clause */
    struct SrcCount *pSrcCount;                /* Counting column references */
  } u;
};

/* Forward declarations */
SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);
12426
12427
12428
12429
12430
12431
12432











12433
12434
12435
12436
12437
12438
12439
    char *zName;                    /* Name of this CTE */
    ExprList *pCols;                /* List of explicit column names, or NULL */
    Select *pSelect;                /* The definition of this CTE */
    const char *zErr;               /* Error message for circular references */
  } a[1];
};












/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE_SKIP_UTF8(zIn) {                        \
  if( (*(zIn++))>=0xc0 ){                              \
    while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \







>
>
>
>
>
>
>
>
>
>
>







12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
    char *zName;                    /* Name of this CTE */
    ExprList *pCols;                /* List of explicit column names, or NULL */
    Select *pSelect;                /* The definition of this CTE */
    const char *zErr;               /* Error message for circular references */
  } a[1];
};

#ifdef SQLITE_DEBUG
/*
** An instance of the TreeView object is used for printing the content of
** data structures on sqlite3DebugPrintf() using a tree-like view.
*/
struct TreeView {
  int iLevel;             /* Which level of the tree we are on */
  u8  bLine[100];         /* Draw vertical in column i if bLine[i] is true */
};
#endif /* SQLITE_DEBUG */

/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE_SKIP_UTF8(zIn) {                        \
  if( (*(zIn++))>=0xc0 ){                              \
    while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
12491
12492
12493
12494
12495
12496
12497

12498
12499
12500
12501
12502
12503
12504
# define sqlite3Isspace(x)   isspace((unsigned char)(x))
# define sqlite3Isalnum(x)   isalnum((unsigned char)(x))
# define sqlite3Isalpha(x)   isalpha((unsigned char)(x))
# define sqlite3Isdigit(x)   isdigit((unsigned char)(x))
# define sqlite3Isxdigit(x)  isxdigit((unsigned char)(x))
# define sqlite3Tolower(x)   tolower((unsigned char)(x))
#endif


/*
** Internal function prototypes
*/
#define sqlite3StrICmp sqlite3_stricmp
SQLITE_PRIVATE int sqlite3Strlen30(const char*);
#define sqlite3StrNICmp sqlite3_strnicmp







>







12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
# define sqlite3Isspace(x)   isspace((unsigned char)(x))
# define sqlite3Isalnum(x)   isalnum((unsigned char)(x))
# define sqlite3Isalpha(x)   isalpha((unsigned char)(x))
# define sqlite3Isdigit(x)   isdigit((unsigned char)(x))
# define sqlite3Isxdigit(x)  isxdigit((unsigned char)(x))
# define sqlite3Tolower(x)   tolower((unsigned char)(x))
#endif
SQLITE_PRIVATE int sqlite3IsIdChar(u8);

/*
** Internal function prototypes
*/
#define sqlite3StrICmp sqlite3_stricmp
SQLITE_PRIVATE int sqlite3Strlen30(const char*);
#define sqlite3StrNICmp sqlite3_strnicmp
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE   void sqlite3DebugPrintf(const char*, ...);
#endif
#if defined(SQLITE_TEST)
SQLITE_PRIVATE   void *sqlite3TestTextToPtr(const char*);
#endif

/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
SQLITE_PRIVATE   void sqlite3ExplainBegin(Vdbe*);
SQLITE_PRIVATE   void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
SQLITE_PRIVATE   void sqlite3ExplainNL(Vdbe*);
SQLITE_PRIVATE   void sqlite3ExplainPush(Vdbe*);
SQLITE_PRIVATE   void sqlite3ExplainPop(Vdbe*);
SQLITE_PRIVATE   void sqlite3ExplainFinish(Vdbe*);
SQLITE_PRIVATE   void sqlite3ExplainSelect(Vdbe*, Select*);
SQLITE_PRIVATE   void sqlite3ExplainExpr(Vdbe*, Expr*);
SQLITE_PRIVATE   void sqlite3ExplainExprList(Vdbe*, ExprList*);
SQLITE_PRIVATE   const char *sqlite3VdbeExplanation(Vdbe*);
#else
# define sqlite3ExplainBegin(X)
# define sqlite3ExplainSelect(A,B)
# define sqlite3ExplainExpr(A,B)
# define sqlite3ExplainExprList(A,B)
# define sqlite3ExplainFinish(X)
# define sqlite3VdbeExplanation(X) 0
#endif


SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
SQLITE_PRIVATE int sqlite3Dequote(char*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);







<
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
<
<
<







12765
12766
12767
12768
12769
12770
12771

12772
12773
12774
12775
12776
12777
12778

12779









12780
12781
12782
12783
12784
12785
12786
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE   void sqlite3DebugPrintf(const char*, ...);
#endif
#if defined(SQLITE_TEST)
SQLITE_PRIVATE   void *sqlite3TestTextToPtr(const char*);
#endif


#if defined(SQLITE_DEBUG)
SQLITE_PRIVATE   TreeView *sqlite3TreeViewPush(TreeView*,u8);
SQLITE_PRIVATE   void sqlite3TreeViewPop(TreeView*);
SQLITE_PRIVATE   void sqlite3TreeViewLine(TreeView*, const char*, ...);
SQLITE_PRIVATE   void sqlite3TreeViewItem(TreeView*, const char*, u8);
SQLITE_PRIVATE   void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
SQLITE_PRIVATE   void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);

SQLITE_PRIVATE   void sqlite3TreeViewSelect(TreeView*, const Select*, u8);









#endif


SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
SQLITE_PRIVATE int sqlite3Dequote(char*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
12789
12790
12791
12792
12793
12794
12795
12796

12797
12798
12799
12800
12801
12802
12803
SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);

SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);







|
>







12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
12813
12814
12815
12816
12817
12818
12819





12820
12821
12822
12823
12824
12825
12826
SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*);
SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*);
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);





SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);







>
>
>
>
>







12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*);
SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*);
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
#if SELECTTRACE_ENABLED
SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
#else
# define sqlite3SelectSetName(A,B)
#endif
SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
);
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);

SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);







|







13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
);
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);

SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
SQLITE_PRIVATE   int sqlite3MemdebugNoType(void*,u8);
#else
# define sqlite3MemdebugSetType(X,Y)  /* no-op */
# define sqlite3MemdebugHasType(X,Y)  1
# define sqlite3MemdebugNoType(X,Y)   1
#endif
#define MEMTYPE_HEAP       0x01  /* General heap allocations */
#define MEMTYPE_LOOKASIDE  0x02  /* Might have been lookaside memory */
#define MEMTYPE_SCRATCH    0x04  /* Scratch allocations */
#define MEMTYPE_PCACHE     0x08  /* Page cache allocations */
#define MEMTYPE_DB         0x10  /* Uses sqlite3DbMalloc, not sqlite_malloc */

/*
** Threading interface
*/
#if SQLITE_MAX_WORKER_THREADS>0
SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);







|


<







13461
13462
13463
13464
13465
13466
13467
13468
13469
13470

13471
13472
13473
13474
13475
13476
13477
SQLITE_PRIVATE   int sqlite3MemdebugNoType(void*,u8);
#else
# define sqlite3MemdebugSetType(X,Y)  /* no-op */
# define sqlite3MemdebugHasType(X,Y)  1
# define sqlite3MemdebugNoType(X,Y)   1
#endif
#define MEMTYPE_HEAP       0x01  /* General heap allocations */
#define MEMTYPE_LOOKASIDE  0x02  /* Heap that might have been lookaside */
#define MEMTYPE_SCRATCH    0x04  /* Scratch allocations */
#define MEMTYPE_PCACHE     0x08  /* Page cache allocations */


/*
** Threading interface
*/
#if SQLITE_MAX_WORKER_THREADS>0
SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
13437
13438
13439
13440
13441
13442
13443











13444
13445
13446
13447




13448
13449
13450
13451
13452
13453
13454
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
};
#endif












#ifndef SQLITE_USE_URI
# define  SQLITE_USE_URI 0
#endif





#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#endif

/*
** The following singleton contains the global configuration for
** the SQLite library.







>
>
>
>
>
>
>
>
>
>
>




>
>
>
>







13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
};
#endif

/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
** compatibility for legacy applications, the URI filename capability is
** disabled by default.
**
** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
**
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
*/
#ifndef SQLITE_USE_URI
# define  SQLITE_USE_URI 0
#endif

/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#endif

/*
** The following singleton contains the global configuration for
** the SQLite library.
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
13542
13543
13544
13545
** a different position in the file.  This allows code that has to
** deal with the pending byte to run on files that are much smaller
** than 1 GiB.  The sqlite3_test_control() interface can be used to
** move the pending byte.
**
** IMPORTANT:  Changing the pending byte to any value other than
** 0x40000000 results in an incompatible database file format!
** Changing the pending byte during operating results in undefined
** and dileterious behavior.
*/
#ifndef SQLITE_OMIT_WSD
SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
#endif

/*
** Properties of opcodes.  The OPFLG_INITIALIZER macro is







|
|







13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
** a different position in the file.  This allows code that has to
** deal with the pending byte to run on files that are much smaller
** than 1 GiB.  The sqlite3_test_control() interface can be used to
** move the pending byte.
**
** IMPORTANT:  Changing the pending byte to any value other than
** 0x40000000 results in an incompatible database file format!
** Changing the pending byte during operation will result in undefined
** and incorrect behavior.
*/
#ifndef SQLITE_OMIT_WSD
SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
#endif

/*
** Properties of opcodes.  The OPFLG_INITIALIZER macro is
13610
13611
13612
13613
13614
13615
13616



13617
13618
13619
13620
13621
13622
13623
  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
#endif
#ifdef SQLITE_DISABLE_DIRSYNC
  "DISABLE_DIRSYNC",
#endif
#ifdef SQLITE_DISABLE_LFS
  "DISABLE_LFS",



#endif
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
  "ENABLE_ATOMIC_WRITE",
#endif
#ifdef SQLITE_ENABLE_CEROD
  "ENABLE_CEROD",
#endif







>
>
>







13795
13796
13797
13798
13799
13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
#endif
#ifdef SQLITE_DISABLE_DIRSYNC
  "DISABLE_DIRSYNC",
#endif
#ifdef SQLITE_DISABLE_LFS
  "DISABLE_LFS",
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
  "ENABLE_API_ARMOR",
#endif
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
  "ENABLE_ATOMIC_WRITE",
#endif
#ifdef SQLITE_ENABLE_CEROD
  "ENABLE_CEROD",
#endif
13936
13937
13938
13939
13940
13941
13942







13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
** was used and false if not.
**
** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
** is not required for a match.
*/
SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
  int i, n;







  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
  n = sqlite3Strlen30(zOptName);

  /* Since ArraySize(azCompileOpt) is normally in single digits, a
  ** linear search is adequate.  No need for a binary search. */
  for(i=0; i<ArraySize(azCompileOpt); i++){
    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
     && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0
    ){
      return 1;
    }
  }
  return 0;
}








>
>
>
>
>
>
>







|







14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
14151
14152
** was used and false if not.
**
** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
** is not required for a match.
*/
SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
  int i, n;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( zOptName==0 ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
  n = sqlite3Strlen30(zOptName);

  /* Since ArraySize(azCompileOpt) is normally in single digits, a
  ** linear search is adequate.  No need for a binary search. */
  for(i=0; i<ArraySize(azCompileOpt); i++){
    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
    ){
      return 1;
    }
  }
  return 0;
}

14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091

14092
14093
14094
14095
14096
14097
14098
  i16 nField;           /* Number of fields in the header */
  u16 nHdrParsed;       /* Number of header fields parsed so far */
#ifdef SQLITE_DEBUG
  u8 seekOp;            /* Most recent seek operation on this cursor */
#endif
  i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
  u8 nullRow;           /* True if pointing to a row with no data */
  u8 rowidIsValid;      /* True if lastRowid is valid */
  u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
  Bool isEphemeral:1;   /* True for an ephemeral table */
  Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
  Bool isTable:1;       /* True if a table requiring integer keys */
  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
  Pgno pgnoRoot;        /* Root page of the open btree cursor */
  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
  i64 seqCount;         /* Sequence counter */
  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
  i64 lastRowid;        /* Rowid being deleted by OP_Delete */
  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */

  /* Cached information about the header for the data record that the
  ** cursor is currently pointing to.  Only valid if cacheStatus matches
  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
  ** the cache is out of date.
  **
  ** aRow might point to (ephemeral) data for the current row, or it might
  ** be NULL.
  */
  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
  u32 payloadSize;      /* Total number of bytes in the record */
  u32 szRow;            /* Byte available in aRow */
  u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
  const u8 *aRow;       /* Data for the current row, if all on one page */

  u32 aType[1];         /* Type values for all entries in the record */
  /* 2*nField extra array elements allocated for aType[], beyond the one
  ** static element declared in the structure.  nField total array slots for
  ** aType[] and nField+1 array slots for aOffset[] */
};
typedef struct VdbeCursor VdbeCursor;








<









<
















>







14253
14254
14255
14256
14257
14258
14259

14260
14261
14262
14263
14264
14265
14266
14267
14268

14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
  i16 nField;           /* Number of fields in the header */
  u16 nHdrParsed;       /* Number of header fields parsed so far */
#ifdef SQLITE_DEBUG
  u8 seekOp;            /* Most recent seek operation on this cursor */
#endif
  i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
  u8 nullRow;           /* True if pointing to a row with no data */

  u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
  Bool isEphemeral:1;   /* True for an ephemeral table */
  Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
  Bool isTable:1;       /* True if a table requiring integer keys */
  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
  Pgno pgnoRoot;        /* Root page of the open btree cursor */
  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
  i64 seqCount;         /* Sequence counter */
  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */

  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */

  /* Cached information about the header for the data record that the
  ** cursor is currently pointing to.  Only valid if cacheStatus matches
  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
  ** the cache is out of date.
  **
  ** aRow might point to (ephemeral) data for the current row, or it might
  ** be NULL.
  */
  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
  u32 payloadSize;      /* Total number of bytes in the record */
  u32 szRow;            /* Byte available in aRow */
  u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
  const u8 *aRow;       /* Data for the current row, if all on one page */
  u32 *aOffset;         /* Pointer to aType[nField] */
  u32 aType[1];         /* Type values for all entries in the record */
  /* 2*nField extra array elements allocated for aType[], beyond the one
  ** static element declared in the structure.  nField total array slots for
  ** aType[] and nField+1 array slots for aOffset[] */
};
typedef struct VdbeCursor VdbeCursor;

14118
14119
14120
14121
14122
14123
14124

14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137

14138
14139
14140
14141
14142
14143
14144
** set to NULL if the currently executing frame is the main program.
*/
typedef struct VdbeFrame VdbeFrame;
struct VdbeFrame {
  Vdbe *v;                /* VM this frame belongs to */
  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
  Op *aOp;                /* Program instructions for parent frame */

  Mem *aMem;              /* Array of memory cells for parent frame */
  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
  void *token;            /* Copy of SubProgram.token */
  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
  int nCursor;            /* Number of entries in apCsr */
  int pc;                 /* Program Counter in parent (calling) frame */
  int nOp;                /* Size of aOp array */
  int nMem;               /* Number of entries in aMem */
  int nOnceFlag;          /* Number of entries in aOnceFlag */
  int nChildMem;          /* Number of memory cells for child frame */
  int nChildCsr;          /* Number of cursors for child frame */
  int nChange;            /* Statement changes (Vdbe.nChanges)     */

};

#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])

/*
** A value for VdbeCursor.cacheValid that means the cache is always invalid.
*/







>












|
>







14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
14335
14336
14337
14338
14339
14340
** set to NULL if the currently executing frame is the main program.
*/
typedef struct VdbeFrame VdbeFrame;
struct VdbeFrame {
  Vdbe *v;                /* VM this frame belongs to */
  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
  Op *aOp;                /* Program instructions for parent frame */
  i64 *anExec;            /* Event counters from parent frame */
  Mem *aMem;              /* Array of memory cells for parent frame */
  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
  void *token;            /* Copy of SubProgram.token */
  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
  int nCursor;            /* Number of entries in apCsr */
  int pc;                 /* Program Counter in parent (calling) frame */
  int nOp;                /* Size of aOp array */
  int nMem;               /* Number of entries in aMem */
  int nOnceFlag;          /* Number of entries in aOnceFlag */
  int nChildMem;          /* Number of memory cells for child frame */
  int nChildCsr;          /* Number of cursors for child frame */
  int nChange;            /* Statement changes (Vdbe.nChange)     */
  int nDbChange;          /* Value of db->nChange */
};

#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])

/*
** A value for VdbeCursor.cacheValid that means the cache is always invalid.
*/
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
14173
14174
14175
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
  int n;              /* Number of characters in string value, excluding '\0' */
  char *z;            /* String or BLOB value */
  /* ShallowCopy only needs to copy the information above */
  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
  int szMalloc;       /* Size of the zMalloc allocation */
  int iPadding1;      /* Padding for 8-byte alignment */
  sqlite3 *db;        /* The associated database connection */
  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
#ifdef SQLITE_DEBUG
  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
#endif
};







|







14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
  int n;              /* Number of characters in string value, excluding '\0' */
  char *z;            /* String or BLOB value */
  /* ShallowCopy only needs to copy the information above */
  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
  int szMalloc;       /* Size of the zMalloc allocation */
  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
  sqlite3 *db;        /* The associated database connection */
  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
#ifdef SQLITE_DEBUG
  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
#endif
};
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  Mem *pOut;            /* The return value is stored here */
  FuncDef *pFunc;       /* Pointer to function information */
  Mem *pMem;            /* Memory cell used to store aggregate context */
  CollSeq *pColl;       /* Collating sequence */
  Vdbe *pVdbe;          /* The VM that owns this context */
  int iOp;              /* Instruction number of OP_Function */
  int isError;          /* Error code returned by the function. */
  u8 skipFlag;          /* Skip accumulator loading if true */
  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
};








<







14453
14454
14455
14456
14457
14458
14459

14460
14461
14462
14463
14464
14465
14466
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  Mem *pOut;            /* The return value is stored here */
  FuncDef *pFunc;       /* Pointer to function information */
  Mem *pMem;            /* Memory cell used to store aggregate context */

  Vdbe *pVdbe;          /* The VM that owns this context */
  int iOp;              /* Instruction number of OP_Function */
  int isError;          /* Error code returned by the function. */
  u8 skipFlag;          /* Skip accumulator loading if true */
  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
};

14281
14282
14283
14284
14285
14286
14287










14288
14289
14290
14291
14292
14293
14294
  char zBase[100];   /* Initial space */
};

/* A bitfield type for use inside of structures.  Always follow with :N where
** N is the number of bits.
*/
typedef unsigned bft;  /* Bit Field Type */











/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
** is really a pointer to an instance of this structure.







>
>
>
>
>
>
>
>
>
>







14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
14494
14495
14496
14497
14498
14499
  char zBase[100];   /* Initial space */
};

/* A bitfield type for use inside of structures.  Always follow with :N where
** N is the number of bits.
*/
typedef unsigned bft;  /* Bit Field Type */

typedef struct ScanStatus ScanStatus;
struct ScanStatus {
  int addrExplain;                /* OP_Explain for loop */
  int addrLoop;                   /* Address of "loops" counter */
  int addrVisit;                  /* Address of "rows visited" counter */
  int iSelectID;                  /* The "Select-ID" for this loop */
  LogEst nEst;                    /* Estimated output rows per loop */
  char *zName;                    /* Name of table or index */
};

/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
** is really a pointer to an instance of this structure.
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364





14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380

14381
14382
14383
14384
14385
14386
14387
#endif
  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
  char *zSql;             /* Text of the SQL statement that generated this */
  void *pFree;            /* Free this when deleting the vdbe */
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
  Explain *pExplain;      /* The explainer */
  char *zExplain;         /* Explanation of data structures */
#endif
  VdbeFrame *pFrame;      /* Parent frame */
  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
  int nFrame;             /* Number of frames in pFrame list */
  u32 expmask;            /* Binding to these vars invalidates VM */
  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
  int nOnceFlag;          /* Size of array aOnceFlag[] */
  u8 *aOnceFlag;          /* Flags for OP_Once */
  AuxData *pAuxData;      /* Linked list of auxdata allocations */





};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */

/*
** Function prototypes
*/
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);

#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);







<
<
<
<








>
>
>
>
>
















>







14551
14552
14553
14554
14555
14556
14557




14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
#endif
  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
  char *zSql;             /* Text of the SQL statement that generated this */
  void *pFree;            /* Free this when deleting the vdbe */




  VdbeFrame *pFrame;      /* Parent frame */
  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
  int nFrame;             /* Number of frames in pFrame list */
  u32 expmask;            /* Binding to these vars invalidates VM */
  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
  int nOnceFlag;          /* Size of array aOnceFlag[] */
  u8 *aOnceFlag;          /* Flags for OP_Once */
  AuxData *pAuxData;      /* Linked list of auxdata allocations */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  i64 *anExec;            /* Number of times each op has been executed */
  int nScan;              /* Entries in aScan[] */
  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
#endif
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */

/*
** Function prototypes
*/
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
14546
14547
14548
14549
14550
14551
14552



14553
14554
14555
14556
14557
14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571





14572
14573
14574
14575
14576
14577
14578
** then this routine is not threadsafe.
*/
SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
  wsdStatInit;
  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
    return SQLITE_MISUSE_BKPT;
  }



  *pCurrent = wsdStat.nowValue[op];
  *pHighwater = wsdStat.mxValue[op];
  if( resetFlag ){
    wsdStat.mxValue[op] = wsdStat.nowValue[op];
  }
  return SQLITE_OK;
}

/*
** Query status information for a single database connection
*/
SQLITE_API int sqlite3_db_status(
  sqlite3 *db,          /* The database connection whose status is desired */
  int op,               /* Status verb */
  int *pCurrent,        /* Write current value here */
  int *pHighwater,      /* Write high-water mark here */
  int resetFlag         /* Reset high-water mark if true */
){
  int rc = SQLITE_OK;   /* Return code */





  sqlite3_mutex_enter(db->mutex);
  switch( op ){
    case SQLITE_DBSTATUS_LOOKASIDE_USED: {
      *pCurrent = db->lookaside.nOut;
      *pHighwater = db->lookaside.mxOut;
      if( resetFlag ){
        db->lookaside.mxOut = db->lookaside.nOut;







>
>
>



















>
>
>
>
>







14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
14771
14772
14773
14774
14775
14776
14777
14778
14779
14780
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
14791
14792
14793
** then this routine is not threadsafe.
*/
SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
  wsdStatInit;
  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
    return SQLITE_MISUSE_BKPT;
  }
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *pCurrent = wsdStat.nowValue[op];
  *pHighwater = wsdStat.mxValue[op];
  if( resetFlag ){
    wsdStat.mxValue[op] = wsdStat.nowValue[op];
  }
  return SQLITE_OK;
}

/*
** Query status information for a single database connection
*/
SQLITE_API int sqlite3_db_status(
  sqlite3 *db,          /* The database connection whose status is desired */
  int op,               /* Status verb */
  int *pCurrent,        /* Write current value here */
  int *pHighwater,      /* Write high-water mark here */
  int resetFlag         /* Reset high-water mark if true */
){
  int rc = SQLITE_OK;   /* Return code */
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
    return SQLITE_MISUSE_BKPT;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  switch( op ){
    case SQLITE_DBSTATUS_LOOKASIDE_USED: {
      *pCurrent = db->lookaside.nOut;
      *pHighwater = db->lookaside.mxOut;
      if( resetFlag ){
        db->lookaside.mxOut = db->lookaside.nOut;
14673
14674
14675
14676
14677
14678
14679
14680
14681
14682
14683
14684
14685
14686
14687
      db->pnBytesFreed = &nByte;
      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
        sqlite3VdbeClearObject(db, pVdbe);
        sqlite3DbFree(db, pVdbe);
      }
      db->pnBytesFreed = 0;

      *pHighwater = 0;
      *pCurrent = nByte;

      break;
    }

    /*
    ** Set *pCurrent to the total cache hits or misses encountered by all







|







14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
      db->pnBytesFreed = &nByte;
      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
        sqlite3VdbeClearObject(db, pVdbe);
        sqlite3DbFree(db, pVdbe);
      }
      db->pnBytesFreed = 0;

      *pHighwater = 0;  /* IMP: R-64479-57858 */
      *pCurrent = nByte;

      break;
    }

    /*
    ** Set *pCurrent to the total cache hits or misses encountered by all
14698
14699
14700
14701
14702
14703
14704
14705


14706
14707
14708
14709
14710
14711
14712
14713
14714
14715
14716
14717
14718
14719
14720
14721
14722

      for(i=0; i<db->nDb; i++){
        if( db->aDb[i].pBt ){
          Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
          sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
        }
      }
      *pHighwater = 0;


      *pCurrent = nRet;
      break;
    }

    /* Set *pCurrent to non-zero if there are unresolved deferred foreign
    ** key constraints.  Set *pCurrent to zero if all foreign key constraints
    ** have been satisfied.  The *pHighwater is always set to zero.
    */
    case SQLITE_DBSTATUS_DEFERRED_FKS: {
      *pHighwater = 0;
      *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
      break;
    }

    default: {
      rc = SQLITE_ERROR;
    }







|
>
>









|







14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939

      for(i=0; i<db->nDb; i++){
        if( db->aDb[i].pBt ){
          Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
          sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
        }
      }
      *pHighwater = 0; /* IMP: R-42420-56072 */
                       /* IMP: R-54100-20147 */
                       /* IMP: R-29431-39229 */
      *pCurrent = nRet;
      break;
    }

    /* Set *pCurrent to non-zero if there are unresolved deferred foreign
    ** key constraints.  Set *pCurrent to zero if all foreign key constraints
    ** have been satisfied.  The *pHighwater is always set to zero.
    */
    case SQLITE_DBSTATUS_DEFERRED_FKS: {
      *pHighwater = 0;  /* IMP: R-11967-56545 */
      *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
      break;
    }

    default: {
      rc = SQLITE_ERROR;
    }
14741
14742
14743
14744
14745
14746
14747
14748
14749
14750
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system. 
**
** 1970-01-01 00:00:00 is JD 2440587.5
** 2000-01-01 00:00:00 is JD 2451544.5
**
** This implementation requires years to be expressed as a 4-digit number
** which means that only dates between 0000-01-01 and 9999-12-31 can
** be represented, even though julian day numbers allow a much wider
** range of dates.
**
** The Gregorian calendar system is used for all dates and times,
** even those that predate the Gregorian calendar.  Historians usually
** use the Julian calendar for dates prior to 1582-10-15 and for some
** dates afterwards, depending on locale.  Beware of this difference.
**
** The conversion algorithms are implemented based on descriptions
** in the following text:
**
**      Jean Meeus
**      Astronomical Algorithms, 2nd Edition, 1998







|














|







14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** SQLite processes all times and dates as julian day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system. 
**
** 1970-01-01 00:00:00 is JD 2440587.5
** 2000-01-01 00:00:00 is JD 2451544.5
**
** This implementation requires years to be expressed as a 4-digit number
** which means that only dates between 0000-01-01 and 9999-12-31 can
** be represented, even though julian day numbers allow a much wider
** range of dates.
**
** The Gregorian calendar system is used for all dates and times,
** even those that predate the Gregorian calendar.  Historians usually
** use the julian calendar for dates prior to 1582-10-15 and for some
** dates afterwards, depending on locale.  Beware of this difference.
**
** The conversion algorithms are implemented based on descriptions
** in the following text:
**
**      Jean Meeus
**      Astronomical Algorithms, 2nd Edition, 1998
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
    return 0;
  }else{
    return 1;
  }
}

/*
** Attempt to parse the given string into a Julian Day Number.  Return
** the number of errors.
**
** The following are acceptable forms for the input string:
**
**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
**      DDDD.DD 
**      now







|







15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
    return 0;
  }else{
    return 1;
  }
}

/*
** Attempt to parse the given string into a julian day number.  Return
** the number of errors.
**
** The following are acceptable forms for the input string:
**
**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
**      DDDD.DD 
**      now
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
**
** Return a string described by FORMAT.  Conversions as follows:
**
**   %d  day of month
**   %f  ** fractional seconds  SS.SSS
**   %H  hour 00-24
**   %j  day of year 000-366
**   %J  ** Julian day number
**   %m  month 01-12
**   %M  minute 00-59
**   %s  seconds since 1970-01-01
**   %S  seconds 00-59
**   %w  day of week 0-6  sunday==0
**   %W  week of year 00-53
**   %Y  year 0000-9999







|







15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
**
** Return a string described by FORMAT.  Conversions as follows:
**
**   %d  day of month
**   %f  ** fractional seconds  SS.SSS
**   %H  hour 00-24
**   %j  day of year 000-366
**   %J  ** julian day number
**   %m  month 01-12
**   %M  minute 00-59
**   %s  seconds since 1970-01-01
**   %S  seconds 00-59
**   %w  day of week 0-6  sunday==0
**   %W  week of year 00-53
**   %Y  year 0000-9999
16224
16225
16226
16227
16228
16229
16230




16231
16232
16233
16234
16235
16236
16237
*/
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
  MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
  int rc = sqlite3_initialize();
  if( rc ) return rc;
#endif




  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(mutex);
  vfsUnlink(pVfs);
  if( makeDflt || vfsList==0 ){
    pVfs->pNext = vfsList;
    vfsList = pVfs;
  }else{







>
>
>
>







16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
*/
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
  MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
  int rc = sqlite3_initialize();
  if( rc ) return rc;
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
#endif

  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(mutex);
  vfsUnlink(pVfs);
  if( makeDflt || vfsList==0 ){
    pVfs->pNext = vfsList;
    vfsList = pVfs;
  }else{
17096
17097
17098
17099
17100
17101
17102
17103
17104
17105
17106
17107
17108
17109
17110
/*
** Return TRUE if the mask of type in eType matches the type of the
** allocation p.  Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
*/
SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */







|







17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
/*
** Return TRUE if the mask of type in eType matches the type of the
** allocation p.  Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
*/
SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
17118
17119
17120
17121
17122
17123
17124
17125
17126
17127
17128
17129
17130
17131
17132
/*
** Return TRUE if the mask of type in eType matches no bits of the type of the
** allocation p.  Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
*/
SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */







|







17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
/*
** Return TRUE if the mask of type in eType matches no bits of the type of the
** allocation p.  Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
*/
SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
18581
18582
18583
18584
18585
18586
18587

18588
18589
18590
18591
18592
18593
18594

/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
  if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;

#endif
  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}

SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
  if( !sqlite3GlobalConfig.bCoreMutex ){
    return 0;







>







18802
18803
18804
18805
18806
18807
18808
18809
18810
18811
18812
18813
18814
18815
18816

/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
  if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
  if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
#endif
  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}

SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
  if( !sqlite3GlobalConfig.bCoreMutex ){
    return 0;
19037
19038
19039
19040
19041
19042
19043
19044
19045




19046
19047
19048
19049
19050
19051
19052
        p->id = iType;
#endif
        pthread_mutex_init(&p->mutex, 0);
      }
      break;
    }
    default: {
      assert( iType-2 >= 0 );
      assert( iType-2 < ArraySize(staticMutexes) );




      p = &staticMutexes[iType-2];
#if SQLITE_MUTEX_NREF
      p->id = iType;
#endif
      break;
    }
  }







|
|
>
>
>
>







19259
19260
19261
19262
19263
19264
19265
19266
19267
19268
19269
19270
19271
19272
19273
19274
19275
19276
19277
19278
        p->id = iType;
#endif
        pthread_mutex_init(&p->mutex, 0);
      }
      break;
    }
    default: {
#ifdef SQLITE_ENABLE_API_ARMOR
      if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
        (void)SQLITE_MISUSE_BKPT;
        return 0;
      }
#endif
      p = &staticMutexes[iType-2];
#if SQLITE_MUTEX_NREF
      p->id = iType;
#endif
      break;
    }
  }
20193
20194
20195
20196
20197
20198
20199
20200
20201
20202
20203
20204
20205
20206
20207
  }else if( sqlite3GlobalConfig.bMemstat ){
    sqlite3_mutex_enter(mem0.mutex);
    mallocWithAlarm((int)n, &p);
    sqlite3_mutex_leave(mem0.mutex);
  }else{
    p = sqlite3GlobalConfig.m.xMalloc((int)n);
  }
  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-04675-44850 */
  return p;
}

/*
** This version of the memory allocation is for use by the application.
** First make sure the memory subsystem is initialized, then do the
** allocation.







|







20419
20420
20421
20422
20423
20424
20425
20426
20427
20428
20429
20430
20431
20432
20433
  }else if( sqlite3GlobalConfig.bMemstat ){
    sqlite3_mutex_enter(mem0.mutex);
    mallocWithAlarm((int)n, &p);
    sqlite3_mutex_leave(mem0.mutex);
  }else{
    p = sqlite3GlobalConfig.m.xMalloc((int)n);
  }
  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-11148-40995 */
  return p;
}

/*
** This version of the memory allocation is for use by the application.
** First make sure the memory subsystem is initialized, then do the
** allocation.
20260
20261
20262
20263
20264
20265
20266

20267
20268

20269
20270

20271
20272
20273
20274
20275
20276
20277
20278
    }
    sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
  }
  assert( sqlite3_mutex_notheld(mem0.mutex) );


#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)

  /* Verify that no more than two scratch allocations per thread
  ** are outstanding at one time.  (This is only checked in the

  ** single-threaded case since checking in the multi-threaded case
  ** would be much more complicated.) */

  assert( scratchAllocOut<=1 );
  if( p ) scratchAllocOut++;
#endif

  return p;
}
SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
  if( p ){







>
|
<
>
|
<
>
|







20486
20487
20488
20489
20490
20491
20492
20493
20494

20495
20496

20497
20498
20499
20500
20501
20502
20503
20504
20505
    }
    sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
  }
  assert( sqlite3_mutex_notheld(mem0.mutex) );


#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
  /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
  ** buffers per thread.

  **
  ** This can only be checked in single-threaded mode.

  */
  assert( scratchAllocOut==0 );
  if( p ) scratchAllocOut++;
#endif

  return p;
}
SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
  if( p ){
20330
20331
20332
20333
20334
20335
20336
20337
20338
20339
20340
20341


20342
20343
20344
20345
20346
20347
20348
20349
20350
20351
20352
20353
20354
20355


20356
20357
20358
20359
20360
20361
20362
20363
20364
20365

20366
20367
20368
20369
20370
20371
20372

/*
** Return the size of a memory allocation previously obtained from
** sqlite3Malloc() or sqlite3_malloc().
*/
SQLITE_PRIVATE int sqlite3MallocSize(void *p){
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
  return sqlite3GlobalConfig.m.xSize(p);
}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
  if( db==0 ){


    return sqlite3MallocSize(p);
  }else{
    assert( sqlite3_mutex_held(db->mutex) );
    if( isLookaside(db, p) ){
      return db->lookaside.sz;
    }else{
      assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
      assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
      assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
      return sqlite3GlobalConfig.m.xSize(p);
    }
  }
}
SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){


  return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
}

/*
** Free memory previously obtained from sqlite3Malloc().
*/
SQLITE_API void sqlite3_free(void *p){
  if( p==0 ) return;  /* IMP: R-49053-54554 */
  assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );

  if( sqlite3GlobalConfig.bMemstat ){
    sqlite3_mutex_enter(mem0.mutex);
    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
    sqlite3GlobalConfig.m.xFree(p);
    sqlite3_mutex_leave(mem0.mutex);
  }else{







<




>
>






|
|
<





>
>








<

>







20557
20558
20559
20560
20561
20562
20563

20564
20565
20566
20567
20568
20569
20570
20571
20572
20573
20574
20575
20576
20577

20578
20579
20580
20581
20582
20583
20584
20585
20586
20587
20588
20589
20590
20591
20592

20593
20594
20595
20596
20597
20598
20599
20600
20601

/*
** Return the size of a memory allocation previously obtained from
** sqlite3Malloc() or sqlite3_malloc().
*/
SQLITE_PRIVATE int sqlite3MallocSize(void *p){
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );

  return sqlite3GlobalConfig.m.xSize(p);
}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
  if( db==0 ){
    assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
    assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
    return sqlite3MallocSize(p);
  }else{
    assert( sqlite3_mutex_held(db->mutex) );
    if( isLookaside(db, p) ){
      return db->lookaside.sz;
    }else{
      assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
      assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );

      return sqlite3GlobalConfig.m.xSize(p);
    }
  }
}
SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
  assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
}

/*
** Free memory previously obtained from sqlite3Malloc().
*/
SQLITE_API void sqlite3_free(void *p){
  if( p==0 ) return;  /* IMP: R-49053-54554 */

  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
  if( sqlite3GlobalConfig.bMemstat ){
    sqlite3_mutex_enter(mem0.mutex);
    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
    sqlite3GlobalConfig.m.xFree(p);
    sqlite3_mutex_leave(mem0.mutex);
  }else{
20402
20403
20404
20405
20406
20407
20408
20409
20410
20411
20412
20413
20414
20415
20416
20417
20418
20419
20420
20421


20422
20423
20424
20425
20426
20427
20428
20429
20430
20431
20432
20433
#endif
      pBuf->pNext = db->lookaside.pFree;
      db->lookaside.pFree = pBuf;
      db->lookaside.nOut--;
      return;
    }
  }
  assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
  assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
  assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
  sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
  sqlite3_free(p);
}

/*
** Change the size of an existing memory allocation
*/
SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
  int nOld, nNew, nDiff;
  void *pNew;


  if( pOld==0 ){
    return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
  }
  if( nBytes==0 ){
    sqlite3_free(pOld); /* IMP: R-31593-10574 */
    return 0;
  }
  if( nBytes>=0x7fffff00 ){
    /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
    return 0;
  }
  nOld = sqlite3MallocSize(pOld);







|
|











>
>

|


|







20631
20632
20633
20634
20635
20636
20637
20638
20639
20640
20641
20642
20643
20644
20645
20646
20647
20648
20649
20650
20651
20652
20653
20654
20655
20656
20657
20658
20659
20660
20661
20662
20663
20664
#endif
      pBuf->pNext = db->lookaside.pFree;
      db->lookaside.pFree = pBuf;
      db->lookaside.nOut--;
      return;
    }
  }
  assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
  assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
  assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
  sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
  sqlite3_free(p);
}

/*
** Change the size of an existing memory allocation
*/
SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
  int nOld, nNew, nDiff;
  void *pNew;
  assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
  assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
  if( pOld==0 ){
    return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
  }
  if( nBytes==0 ){
    sqlite3_free(pOld); /* IMP: R-26507-47431 */
    return 0;
  }
  if( nBytes>=0x7fffff00 ){
    /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
    return 0;
  }
  nOld = sqlite3MallocSize(pOld);
20441
20442
20443
20444
20445
20446
20447
20448
20449
20450
20451
20452
20453
20454
20455
20456
20457
20458
20459
20460
20461
20462
20463
20464
20465
20466
20467
20468
20469
20470
20471
20472
20473
20474
20475
20476
20477
20478
20479
20480
20481
20482
    sqlite3_mutex_enter(mem0.mutex);
    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
    nDiff = nNew - nOld;
    if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= 
          mem0.alarmThreshold-nDiff ){
      sqlite3MallocAlarm(nDiff);
    }
    assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
    assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
    if( pNew==0 && mem0.alarmCallback ){
      sqlite3MallocAlarm((int)nBytes);
      pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
    }
    if( pNew ){
      nNew = sqlite3MallocSize(pNew);
      sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
    }
    sqlite3_mutex_leave(mem0.mutex);
  }else{
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
  }
  assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
  return pNew;
}

/*
** The public interface to sqlite3Realloc.  Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
*/
SQLITE_API void *sqlite3_realloc(void *pOld, int n){
#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return 0;
#endif
  if( n<0 ) n = 0;
  return sqlite3Realloc(pOld, n);
}
SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return 0;
#endif
  return sqlite3Realloc(pOld, n);







<
<













|











|







20672
20673
20674
20675
20676
20677
20678


20679
20680
20681
20682
20683
20684
20685
20686
20687
20688
20689
20690
20691
20692
20693
20694
20695
20696
20697
20698
20699
20700
20701
20702
20703
20704
20705
20706
20707
20708
20709
20710
20711
    sqlite3_mutex_enter(mem0.mutex);
    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
    nDiff = nNew - nOld;
    if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= 
          mem0.alarmThreshold-nDiff ){
      sqlite3MallocAlarm(nDiff);
    }


    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
    if( pNew==0 && mem0.alarmCallback ){
      sqlite3MallocAlarm((int)nBytes);
      pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
    }
    if( pNew ){
      nNew = sqlite3MallocSize(pNew);
      sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
    }
    sqlite3_mutex_leave(mem0.mutex);
  }else{
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
  }
  assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */
  return pNew;
}

/*
** The public interface to sqlite3Realloc.  Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
*/
SQLITE_API void *sqlite3_realloc(void *pOld, int n){
#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return 0;
#endif
  if( n<0 ) n = 0;  /* IMP: R-26507-47431 */
  return sqlite3Realloc(pOld, n);
}
SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return 0;
#endif
  return sqlite3Realloc(pOld, n);
20555
20556
20557
20558
20559
20560
20561
20562
20563
20564
20565
20566
20567
20568
20569
20570
    return 0;
  }
#endif
  p = sqlite3Malloc(n);
  if( !p && db ){
    db->mallocFailed = 1;
  }
  sqlite3MemdebugSetType(p, MEMTYPE_DB |
         ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
  return p;
}

/*
** Resize the block of memory pointed to by p to n bytes. If the
** resize fails, set the mallocFailed flag in the connection object.
*/







|
|







20784
20785
20786
20787
20788
20789
20790
20791
20792
20793
20794
20795
20796
20797
20798
20799
    return 0;
  }
#endif
  p = sqlite3Malloc(n);
  if( !p && db ){
    db->mallocFailed = 1;
  }
  sqlite3MemdebugSetType(p, 
         (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
  return p;
}

/*
** Resize the block of memory pointed to by p to n bytes. If the
** resize fails, set the mallocFailed flag in the connection object.
*/
20582
20583
20584
20585
20586
20587
20588
20589
20590
20591
20592
20593
20594
20595
20596
20597
20598
20599
20600
20601
20602
20603
20604
      }
      pNew = sqlite3DbMallocRaw(db, n);
      if( pNew ){
        memcpy(pNew, p, db->lookaside.sz);
        sqlite3DbFree(db, p);
      }
    }else{
      assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
      assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
      pNew = sqlite3_realloc64(p, n);
      if( !pNew ){
        sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
        db->mallocFailed = 1;
      }
      sqlite3MemdebugSetType(pNew, MEMTYPE_DB | 
            (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
    }
  }
  return pNew;
}

/*







|
|



<


|







20811
20812
20813
20814
20815
20816
20817
20818
20819
20820
20821
20822

20823
20824
20825
20826
20827
20828
20829
20830
20831
20832
      }
      pNew = sqlite3DbMallocRaw(db, n);
      if( pNew ){
        memcpy(pNew, p, db->lookaside.sz);
        sqlite3DbFree(db, p);
      }
    }else{
      assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
      assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
      pNew = sqlite3_realloc64(p, n);
      if( !pNew ){

        db->mallocFailed = 1;
      }
      sqlite3MemdebugSetType(pNew,
            (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
    }
  }
  return pNew;
}

/*
20720
20721
20722
20723
20724
20725
20726
20727
20728
20729
20730
20731
20732
20733
20734
20735
20736
20737
20738
/*
** If the strchrnul() library function is available, then set
** HAVE_STRCHRNUL.  If that routine is not available, this module
** will supply its own.  The built-in version is slower than
** the glibc version so the glibc version is definitely preferred.
*/
#if !defined(HAVE_STRCHRNUL)
# if defined(linux)
#  define HAVE_STRCHRNUL 1
# else
#  define HAVE_STRCHRNUL 0
# endif
#endif


/*
** Conversion types fall into various categories as defined by the
** following enumeration.
*/







<
<
<
|
<







20948
20949
20950
20951
20952
20953
20954



20955

20956
20957
20958
20959
20960
20961
20962
/*
** If the strchrnul() library function is available, then set
** HAVE_STRCHRNUL.  If that routine is not available, this module
** will supply its own.  The built-in version is slower than
** the glibc version so the glibc version is definitely preferred.
*/
#if !defined(HAVE_STRCHRNUL)



# define HAVE_STRCHRNUL 0

#endif


/*
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
20915
20916
20917
20918
20919
20920
20921
20922
20923
20924
20925
20926
20927
20928
20929
20930
20931
20932







20933
20934
20935
20936
20937
20938
20939
  u8 useIntern;              /* Ok to use internal conversions (ex: %T) */
  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
  sqlite_uint64 longvalue;   /* Value for integer types */
  LONGDOUBLE_TYPE realvalue; /* Value for real types */
  const et_info *infop;      /* Pointer to the appropriate info structure */
  char *zOut;                /* Rendering buffer */
  int nOut;                  /* Size of the rendering buffer */
  char *zExtra;              /* Malloced memory used by some conversion */
#ifndef SQLITE_OMIT_FLOATING_POINT
  int  exp, e2;              /* exponent of real numbers */
  int nsd;                   /* Number of significant digits returned */
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
#endif
  PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
  char buf[etBUFSIZE];       /* Conversion buffer */








  bufpt = 0;
  if( bFlags ){
    if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
      pArgList = va_arg(ap, PrintfArguments*);
    }
    useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
  }else{







|










>
>
>
>
>
>
>







21139
21140
21141
21142
21143
21144
21145
21146
21147
21148
21149
21150
21151
21152
21153
21154
21155
21156
21157
21158
21159
21160
21161
21162
21163
21164
21165
21166
21167
21168
21169
21170
  u8 useIntern;              /* Ok to use internal conversions (ex: %T) */
  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
  sqlite_uint64 longvalue;   /* Value for integer types */
  LONGDOUBLE_TYPE realvalue; /* Value for real types */
  const et_info *infop;      /* Pointer to the appropriate info structure */
  char *zOut;                /* Rendering buffer */
  int nOut;                  /* Size of the rendering buffer */
  char *zExtra = 0;          /* Malloced memory used by some conversion */
#ifndef SQLITE_OMIT_FLOATING_POINT
  int  exp, e2;              /* exponent of real numbers */
  int nsd;                   /* Number of significant digits returned */
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
#endif
  PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
  char buf[etBUFSIZE];       /* Conversion buffer */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( ap==0 ){
    (void)SQLITE_MISUSE_BKPT;
    sqlite3StrAccumReset(pAccum);
    return;
  }
#endif
  bufpt = 0;
  if( bFlags ){
    if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
      pArgList = va_arg(ap, PrintfArguments*);
    }
    useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
  }else{
21032
21033
21034
21035
21036
21037
21038
21039
21040
21041
21042
21043
21044
21045
21046
          xtype = infop->type;
        }else{
          return;
        }
        break;
      }
    }
    zExtra = 0;

    /*
    ** At this point, variables are initialized as follows:
    **
    **   flag_alternateform          TRUE if a '#' is present.
    **   flag_altform2               TRUE if a '!' is present.
    **   flag_plussign               TRUE if a '+' is present.







<







21263
21264
21265
21266
21267
21268
21269

21270
21271
21272
21273
21274
21275
21276
          xtype = infop->type;
        }else{
          return;
        }
        break;
      }
    }


    /*
    ** At this point, variables are initialized as follows:
    **
    **   flag_alternateform          TRUE if a '#' is present.
    **   flag_altform2               TRUE if a '!' is present.
    **   flag_plussign               TRUE if a '+' is present.
21323
21324
21325
21326
21327
21328
21329
21330
21331
21332
21333
21334


21335
21336




21337
21338
21339
21340
21341
21342
21343
      case etCHARX:
        if( bArgList ){
          bufpt = getTextArg(pArgList);
          c = bufpt ? bufpt[0] : 0;
        }else{
          c = va_arg(ap,int);
        }
        buf[0] = (char)c;
        if( precision>=0 ){
          for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
          length = precision;
        }else{


          length =1;
        }




        bufpt = buf;
        break;
      case etSTRING:
      case etDYNSTRING:
        if( bArgList ){
          bufpt = getTextArg(pArgList);
        }else{







<
|
<
|
<
>
>
|
|
>
>
>
>







21553
21554
21555
21556
21557
21558
21559

21560

21561

21562
21563
21564
21565
21566
21567
21568
21569
21570
21571
21572
21573
21574
21575
21576
      case etCHARX:
        if( bArgList ){
          bufpt = getTextArg(pArgList);
          c = bufpt ? bufpt[0] : 0;
        }else{
          c = va_arg(ap,int);
        }

        if( precision>1 ){

          width -= precision-1;

          if( width>1 && !flag_leftjustify ){
            sqlite3AppendChar(pAccum, width-1, ' ');
            width = 0;
          }
          sqlite3AppendChar(pAccum, precision-1, c);
        }
        length = 1;
        buf[0] = c;
        bufpt = buf;
        break;
      case etSTRING:
      case etDYNSTRING:
        if( bArgList ){
          bufpt = getTextArg(pArgList);
        }else{
21430
21431
21432
21433
21434
21435
21436
21437
21438
21439
21440
21441



21442
21443
21444
21445
21446
21447
21448
    }/* End switch over the format type */
    /*
    ** The text of the conversion is pointed to by "bufpt" and is
    ** "length" characters long.  The field width is "width".  Do
    ** the output.
    */
    width -= length;
    if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
    sqlite3StrAccumAppend(pAccum, bufpt, length);
    if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width);

    if( zExtra ) sqlite3_free(zExtra);



  }/* End for loop over the format string */
} /* End of function */

/*
** Enlarge the memory allocation on a StrAccum object so that it is
** able to accept at least N more bytes of text.
**







|

|

|
>
>
>







21663
21664
21665
21666
21667
21668
21669
21670
21671
21672
21673
21674
21675
21676
21677
21678
21679
21680
21681
21682
21683
21684
    }/* End switch over the format type */
    /*
    ** The text of the conversion is pointed to by "bufpt" and is
    ** "length" characters long.  The field width is "width".  Do
    ** the output.
    */
    width -= length;
    if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
    sqlite3StrAccumAppend(pAccum, bufpt, length);
    if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');

    if( zExtra ){
      sqlite3_free(zExtra);
      zExtra = 0;
    }
  }/* End for loop over the format string */
} /* End of function */

/*
** Enlarge the memory allocation on a StrAccum object so that it is
** able to accept at least N more bytes of text.
**
21461
21462
21463
21464
21465
21466
21467





21468
21469
21470
21471
21472
21473
21474
21475
21476
21477
21478
21479
21480
21481
21482
21483

21484
21485
21486
21487
21488
21489
21490
21491
21492
21493
21494
21495
21496
21497
21498
21499
21500
21501
21502
21503
21504
21505
    N = p->nAlloc - p->nChar - 1;
    setStrAccumError(p, STRACCUM_TOOBIG);
    return N;
  }else{
    char *zOld = (p->zText==p->zBase ? 0 : p->zText);
    i64 szNew = p->nChar;
    szNew += N + 1;





    if( szNew > p->mxAlloc ){
      sqlite3StrAccumReset(p);
      setStrAccumError(p, STRACCUM_TOOBIG);
      return 0;
    }else{
      p->nAlloc = (int)szNew;
    }
    if( p->useMalloc==1 ){
      zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
    }else{
      zNew = sqlite3_realloc(zOld, p->nAlloc);
    }
    if( zNew ){
      assert( p->zText!=0 || p->nChar==0 );
      if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
      p->zText = zNew;

    }else{
      sqlite3StrAccumReset(p);
      setStrAccumError(p, STRACCUM_NOMEM);
      return 0;
    }
  }
  return N;
}

/*
** Append N space characters to the given string buffer.
*/
SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *p, int N){
  if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
  while( (N--)>0 ) p->zText[p->nChar++] = ' ';
}

/*
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**
** This is a helper routine to sqlite3StrAccumAppend() that does special-case







>
>
>
>
>
















>










|

|

|







21697
21698
21699
21700
21701
21702
21703
21704
21705
21706
21707
21708
21709
21710
21711
21712
21713
21714
21715
21716
21717
21718
21719
21720
21721
21722
21723
21724
21725
21726
21727
21728
21729
21730
21731
21732
21733
21734
21735
21736
21737
21738
21739
21740
21741
21742
21743
21744
21745
21746
21747
    N = p->nAlloc - p->nChar - 1;
    setStrAccumError(p, STRACCUM_TOOBIG);
    return N;
  }else{
    char *zOld = (p->zText==p->zBase ? 0 : p->zText);
    i64 szNew = p->nChar;
    szNew += N + 1;
    if( szNew+p->nChar<=p->mxAlloc ){
      /* Force exponential buffer size growth as long as it does not overflow,
      ** to avoid having to call this routine too often */
      szNew += p->nChar;
    }
    if( szNew > p->mxAlloc ){
      sqlite3StrAccumReset(p);
      setStrAccumError(p, STRACCUM_TOOBIG);
      return 0;
    }else{
      p->nAlloc = (int)szNew;
    }
    if( p->useMalloc==1 ){
      zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
    }else{
      zNew = sqlite3_realloc(zOld, p->nAlloc);
    }
    if( zNew ){
      assert( p->zText!=0 || p->nChar==0 );
      if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
      p->zText = zNew;
      p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
    }else{
      sqlite3StrAccumReset(p);
      setStrAccumError(p, STRACCUM_NOMEM);
      return 0;
    }
  }
  return N;
}

/*
** Append N copies of character c to the given string buffer.
*/
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
  if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
  while( (N--)>0 ) p->zText[p->nChar++] = c;
}

/*
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**
** This is a helper routine to sqlite3StrAccumAppend() that does special-case
21646
21647
21648
21649
21650
21651
21652







21653
21654
21655
21656
21657
21658
21659
** Print into memory obtained from sqlite3_malloc().  Omit the internal
** %-conversion extensions.
*/
SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
  char *z;
  char zBase[SQLITE_PRINT_BUF_SIZE];
  StrAccum acc;







#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return 0;
#endif
  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
  acc.useMalloc = 2;
  sqlite3VXPrintf(&acc, 0, zFormat, ap);
  z = sqlite3StrAccumFinish(&acc);







>
>
>
>
>
>
>







21888
21889
21890
21891
21892
21893
21894
21895
21896
21897
21898
21899
21900
21901
21902
21903
21904
21905
21906
21907
21908
** Print into memory obtained from sqlite3_malloc().  Omit the internal
** %-conversion extensions.
*/
SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
  char *z;
  char zBase[SQLITE_PRINT_BUF_SIZE];
  StrAccum acc;

#ifdef SQLITE_ENABLE_API_ARMOR  
  if( zFormat==0 ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return 0;
#endif
  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
  acc.useMalloc = 2;
  sqlite3VXPrintf(&acc, 0, zFormat, ap);
  z = sqlite3StrAccumFinish(&acc);
21688
21689
21690
21691
21692
21693
21694







21695
21696
21697
21698
21699
21700
21701
** mistake.
**
** sqlite3_vsnprintf() is the varargs version.
*/
SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
  StrAccum acc;
  if( n<=0 ) return zBuf;







  sqlite3StrAccumInit(&acc, zBuf, n, 0);
  acc.useMalloc = 0;
  sqlite3VXPrintf(&acc, 0, zFormat, ap);
  return sqlite3StrAccumFinish(&acc);
}
SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
  char *z;







>
>
>
>
>
>
>







21937
21938
21939
21940
21941
21942
21943
21944
21945
21946
21947
21948
21949
21950
21951
21952
21953
21954
21955
21956
21957
** mistake.
**
** sqlite3_vsnprintf() is the varargs version.
*/
SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
  StrAccum acc;
  if( n<=0 ) return zBuf;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( zBuf==0 || zFormat==0 ) {
    (void)SQLITE_MISUSE_BKPT;
    if( zBuf && n>0 ) zBuf[0] = 0;
    return zBuf;
  }
#endif
  sqlite3StrAccumInit(&acc, zBuf, n, 0);
  acc.useMalloc = 0;
  sqlite3VXPrintf(&acc, 0, zFormat, ap);
  return sqlite3StrAccumFinish(&acc);
}
SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
  char *z;
21755
21756
21757
21758
21759
21760
21761































































21762
21763
21764
21765
21766
21767
21768
  va_end(ap);
  sqlite3StrAccumFinish(&acc);
  fprintf(stdout,"%s", zBuf);
  fflush(stdout);
}
#endif
































































/*
** variable-argument wrapper around sqlite3VXPrintf().
*/
SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
  va_list ap;
  va_start(ap,zFormat);
  sqlite3VXPrintf(p, bFlags, zFormat, ap);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







22011
22012
22013
22014
22015
22016
22017
22018
22019
22020
22021
22022
22023
22024
22025
22026
22027
22028
22029
22030
22031
22032
22033
22034
22035
22036
22037
22038
22039
22040
22041
22042
22043
22044
22045
22046
22047
22048
22049
22050
22051
22052
22053
22054
22055
22056
22057
22058
22059
22060
22061
22062
22063
22064
22065
22066
22067
22068
22069
22070
22071
22072
22073
22074
22075
22076
22077
22078
22079
22080
22081
22082
22083
22084
22085
22086
22087
  va_end(ap);
  sqlite3StrAccumFinish(&acc);
  fprintf(stdout,"%s", zBuf);
  fflush(stdout);
}
#endif

#ifdef SQLITE_DEBUG
/*************************************************************************
** Routines for implementing the "TreeView" display of hierarchical
** data structures for debugging.
**
** The main entry points (coded elsewhere) are:
**     sqlite3TreeViewExpr(0, pExpr, 0);
**     sqlite3TreeViewExprList(0, pList, 0, 0);
**     sqlite3TreeViewSelect(0, pSelect, 0);
** Insert calls to those routines while debugging in order to display
** a diagram of Expr, ExprList, and Select objects.
**
*/
/* Add a new subitem to the tree.  The moreToFollow flag indicates that this
** is not the last item in the tree. */
SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
  if( p==0 ){
    p = sqlite3_malloc( sizeof(*p) );
    if( p==0 ) return 0;
    memset(p, 0, sizeof(*p));
  }else{
    p->iLevel++;
  }
  assert( moreToFollow==0 || moreToFollow==1 );
  if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
  return p;
}
/* Finished with one layer of the tree */
SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView *p){
  if( p==0 ) return;
  p->iLevel--;
  if( p->iLevel<0 ) sqlite3_free(p);
}
/* Generate a single line of output for the tree, with a prefix that contains
** all the appropriate tree lines */
SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
  va_list ap;
  int i;
  StrAccum acc;
  char zBuf[500];
  sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
  acc.useMalloc = 0;
  if( p ){
    for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
      sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
    }
    sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
  }
  va_start(ap, zFormat);
  sqlite3VXPrintf(&acc, 0, zFormat, ap);
  va_end(ap);
  if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
  sqlite3StrAccumFinish(&acc);
  fprintf(stdout,"%s", zBuf);
  fflush(stdout);
}
/* Shorthand for starting a new tree item that consists of a single label */
SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
  p = sqlite3TreeViewPush(p, moreToFollow);
  sqlite3TreeViewLine(p, "%s", zLabel);
}
#endif /* SQLITE_DEBUG */

/*
** variable-argument wrapper around sqlite3VXPrintf().
*/
SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
  va_list ap;
  va_start(ap,zFormat);
  sqlite3VXPrintf(p, bFlags, zFormat, ap);
21816
21817
21818
21819
21820
21821
21822
21823

21824


21825
21826





21827
21828
21829
21830
21831
21832
21833
21834
  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
# define wsdPrng p[0]
#else
# define wsdPrng sqlite3Prng
#endif

#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);

  sqlite3_mutex_enter(mutex);


#endif






  if( N<=0 ){
    wsdPrng.isInit = 0;
    sqlite3_mutex_leave(mutex);
    return;
  }

  /* Initialize the state of the random number generator once,
  ** the first time this routine is called.  The seed value does







|
>
|
>
>


>
>
>
>
>
|







22135
22136
22137
22138
22139
22140
22141
22142
22143
22144
22145
22146
22147
22148
22149
22150
22151
22152
22153
22154
22155
22156
22157
22158
22159
22160
22161
  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
# define wsdPrng p[0]
#else
# define wsdPrng sqlite3Prng
#endif

#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex;
#endif

#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return;
#endif

#if SQLITE_THREADSAFE
  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
#endif

  sqlite3_mutex_enter(mutex);
  if( N<=0 || pBuf==0 ){
    wsdPrng.isInit = 0;
    sqlite3_mutex_leave(mutex);
    return;
  }

  /* Initialize the state of the random number generator once,
  ** the first time this routine is called.  The seed value does
21994
21995
21996
21997
21998
21999
22000
22001
22002
22003
22004
22005
22006
22007
22008
22009
22010
22011
22012
22013
22014
22015
}

#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
/******************************** End Unix Pthreads *************************/


/********************************* Win32 Threads ****************************/
#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0

#define SQLITE_THREADS_IMPLEMENTED 1  /* Prevent the single-thread code below */
#include <process.h>

/* A running thread */
struct SQLiteThread {
  uintptr_t tid;           /* The thread handle */
  unsigned id;             /* The thread identifier */
  void *(*xTask)(void*);   /* The routine to run as a thread */
  void *pIn;               /* Argument to xTask */
  void *pResult;           /* Result of xTask */
};

/* Thread procedure Win32 compatibility shim */







|






|







22321
22322
22323
22324
22325
22326
22327
22328
22329
22330
22331
22332
22333
22334
22335
22336
22337
22338
22339
22340
22341
22342
}

#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
/******************************** End Unix Pthreads *************************/


/********************************* Win32 Threads ****************************/
#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0

#define SQLITE_THREADS_IMPLEMENTED 1  /* Prevent the single-thread code below */
#include <process.h>

/* A running thread */
struct SQLiteThread {
  void *tid;               /* The thread handle */
  unsigned id;             /* The thread identifier */
  void *(*xTask)(void*);   /* The routine to run as a thread */
  void *pIn;               /* Argument to xTask */
  void *pResult;           /* Result of xTask */
};

/* Thread procedure Win32 compatibility shim */
22049
22050
22051
22052
22053
22054
22055
22056
22057
22058
22059
22060
22061
22062
22063
  p = sqlite3Malloc(sizeof(*p));
  if( p==0 ) return SQLITE_NOMEM;
  if( sqlite3GlobalConfig.bCoreMutex==0 ){
    memset(p, 0, sizeof(*p));
  }else{
    p->xTask = xTask;
    p->pIn = pIn;
    p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
    if( p->tid==0 ){
      memset(p, 0, sizeof(*p));
    }
  }
  if( p->xTask==0 ){
    p->id = GetCurrentThreadId();
    p->pResult = xTask(pIn);







|







22376
22377
22378
22379
22380
22381
22382
22383
22384
22385
22386
22387
22388
22389
22390
  p = sqlite3Malloc(sizeof(*p));
  if( p==0 ) return SQLITE_NOMEM;
  if( sqlite3GlobalConfig.bCoreMutex==0 ){
    memset(p, 0, sizeof(*p));
  }else{
    p->xTask = xTask;
    p->pIn = pIn;
    p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
    if( p->tid==0 ){
      memset(p, 0, sizeof(*p));
    }
  }
  if( p->xTask==0 ){
    p->id = GetCurrentThreadId();
    p->pResult = xTask(pIn);
22087
22088
22089
22090
22091
22092
22093
22094
22095
22096
22097
22098
22099
22100
22101
    assert( bRc );
  }
  if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
  sqlite3_free(p);
  return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
}

#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
/******************************** End Win32 Threads *************************/


/********************************* Single-Threaded **************************/
#ifndef SQLITE_THREADS_IMPLEMENTED
/*
** This implementation does not actually create a new thread.  It does the







|







22414
22415
22416
22417
22418
22419
22420
22421
22422
22423
22424
22425
22426
22427
22428
    assert( bRc );
  }
  if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
  sqlite3_free(p);
  return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
}

#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */
/******************************** End Win32 Threads *************************/


/********************************* Single-Threaded **************************/
#ifndef SQLITE_THREADS_IMPLEMENTED
/*
** This implementation does not actually create a new thread.  It does the
22942
22943
22944
22945
22946
22947
22948





22949
22950
22951
22952
22953
22954
22955





22956
22957
22958
22959
22960
22961
22962
** sqlite3_strnicmp() APIs allow applications and extensions to compare
** the contents of two buffers containing UTF-8 strings in a
** case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
  register unsigned char *a, *b;





  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return UpperToLower[*a] - UpperToLower[*b];
}
SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
  register unsigned char *a, *b;





  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}

/*







>
>
>
>
>







>
>
>
>
>







23269
23270
23271
23272
23273
23274
23275
23276
23277
23278
23279
23280
23281
23282
23283
23284
23285
23286
23287
23288
23289
23290
23291
23292
23293
23294
23295
23296
23297
23298
23299
** sqlite3_strnicmp() APIs allow applications and extensions to compare
** the contents of two buffers containing UTF-8 strings in a
** case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
  register unsigned char *a, *b;
  if( zLeft==0 ){
    return zRight ? -1 : 0;
  }else if( zRight==0 ){
    return 1;
  }
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return UpperToLower[*a] - UpperToLower[*b];
}
SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
  register unsigned char *a, *b;
  if( zLeft==0 ){
    return zRight ? -1 : 0;
  }else if( zRight==0 ){
    return 1;
  }
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}

/*
29657
29658
29659
29660
29661
29662
29663
29664
29665
29666
29667
29668
29669
29670
29671
29672
29673
29674
29675
29676
29677
29678
29679
29680
29681
29682
29683
29684
29685
29686
**
**   *  A constant sqlite3_io_methods object call METHOD that has locking
**      methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
**
**   *  An I/O method finder function called FINDER that returns a pointer
**      to the METHOD object in the previous bullet.
*/
#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK)      \
static const sqlite3_io_methods METHOD = {                                   \
   VERSION,                    /* iVersion */                                \
   CLOSE,                      /* xClose */                                  \
   unixRead,                   /* xRead */                                   \
   unixWrite,                  /* xWrite */                                  \
   unixTruncate,               /* xTruncate */                               \
   unixSync,                   /* xSync */                                   \
   unixFileSize,               /* xFileSize */                               \
   LOCK,                       /* xLock */                                   \
   UNLOCK,                     /* xUnlock */                                 \
   CKLOCK,                     /* xCheckReservedLock */                      \
   unixFileControl,            /* xFileControl */                            \
   unixSectorSize,             /* xSectorSize */                             \
   unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
   unixShmMap,                 /* xShmMap */                                 \
   unixShmLock,                /* xShmLock */                                \
   unixShmBarrier,             /* xShmBarrier */                             \
   unixShmUnmap,               /* xShmUnmap */                               \
   unixFetch,                  /* xFetch */                                  \
   unixUnfetch,                /* xUnfetch */                                \
};                                                                           \
static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \







|














|







29994
29995
29996
29997
29998
29999
30000
30001
30002
30003
30004
30005
30006
30007
30008
30009
30010
30011
30012
30013
30014
30015
30016
30017
30018
30019
30020
30021
30022
30023
**
**   *  A constant sqlite3_io_methods object call METHOD that has locking
**      methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
**
**   *  An I/O method finder function called FINDER that returns a pointer
**      to the METHOD object in the previous bullet.
*/
#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \
static const sqlite3_io_methods METHOD = {                                   \
   VERSION,                    /* iVersion */                                \
   CLOSE,                      /* xClose */                                  \
   unixRead,                   /* xRead */                                   \
   unixWrite,                  /* xWrite */                                  \
   unixTruncate,               /* xTruncate */                               \
   unixSync,                   /* xSync */                                   \
   unixFileSize,               /* xFileSize */                               \
   LOCK,                       /* xLock */                                   \
   UNLOCK,                     /* xUnlock */                                 \
   CKLOCK,                     /* xCheckReservedLock */                      \
   unixFileControl,            /* xFileControl */                            \
   unixSectorSize,             /* xSectorSize */                             \
   unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
   SHMMAP,                     /* xShmMap */                                 \
   unixShmLock,                /* xShmLock */                                \
   unixShmBarrier,             /* xShmBarrier */                             \
   unixShmUnmap,               /* xShmUnmap */                               \
   unixFetch,                  /* xFetch */                                  \
   unixUnfetch,                /* xUnfetch */                                \
};                                                                           \
static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
29698
29699
29700
29701
29702
29703
29704
29705

29706
29707
29708
29709
29710
29711
29712
29713
29714

29715
29716
29717
29718
29719
29720
29721
29722
29723

29724
29725
29726
29727
29728
29729
29730
29731
29732
29733
29734

29735
29736
29737
29738
29739
29740
29741
29742
29743
29744
29745
29746

29747
29748
29749
29750
29751
29752
29753
29754
29755
29756
29757
29758

29759
29760
29761
29762
29763
29764
29765
IOMETHODS(
  posixIoFinder,            /* Finder function name */
  posixIoMethods,           /* sqlite3_io_methods object name */
  3,                        /* shared memory and mmap are enabled */
  unixClose,                /* xClose method */
  unixLock,                 /* xLock method */
  unixUnlock,               /* xUnlock method */
  unixCheckReservedLock     /* xCheckReservedLock method */

)
IOMETHODS(
  nolockIoFinder,           /* Finder function name */
  nolockIoMethods,          /* sqlite3_io_methods object name */
  3,                        /* shared memory is disabled */
  nolockClose,              /* xClose method */
  nolockLock,               /* xLock method */
  nolockUnlock,             /* xUnlock method */
  nolockCheckReservedLock   /* xCheckReservedLock method */

)
IOMETHODS(
  dotlockIoFinder,          /* Finder function name */
  dotlockIoMethods,         /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  dotlockClose,             /* xClose method */
  dotlockLock,              /* xLock method */
  dotlockUnlock,            /* xUnlock method */
  dotlockCheckReservedLock  /* xCheckReservedLock method */

)

#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
IOMETHODS(
  flockIoFinder,            /* Finder function name */
  flockIoMethods,           /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  flockClose,               /* xClose method */
  flockLock,                /* xLock method */
  flockUnlock,              /* xUnlock method */
  flockCheckReservedLock    /* xCheckReservedLock method */

)
#endif

#if OS_VXWORKS
IOMETHODS(
  semIoFinder,              /* Finder function name */
  semIoMethods,             /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  semClose,                 /* xClose method */
  semLock,                  /* xLock method */
  semUnlock,                /* xUnlock method */
  semCheckReservedLock      /* xCheckReservedLock method */

)
#endif

#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
IOMETHODS(
  afpIoFinder,              /* Finder function name */
  afpIoMethods,             /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  afpClose,                 /* xClose method */
  afpLock,                  /* xLock method */
  afpUnlock,                /* xUnlock method */
  afpCheckReservedLock      /* xCheckReservedLock method */

)
#endif

/*
** The proxy locking method is a "super-method" in the sense that it
** opens secondary file descriptors for the conch and lock files and
** it uses proxy, dot-file, AFP, and flock() locking methods on those







|
>








|
>








|
>










|
>











|
>











|
>







30035
30036
30037
30038
30039
30040
30041
30042
30043
30044
30045
30046
30047
30048
30049
30050
30051
30052
30053
30054
30055
30056
30057
30058
30059
30060
30061
30062
30063
30064
30065
30066
30067
30068
30069
30070
30071
30072
30073
30074
30075
30076
30077
30078
30079
30080
30081
30082
30083
30084
30085
30086
30087
30088
30089
30090
30091
30092
30093
30094
30095
30096
30097
30098
30099
30100
30101
30102
30103
30104
30105
30106
30107
30108
IOMETHODS(
  posixIoFinder,            /* Finder function name */
  posixIoMethods,           /* sqlite3_io_methods object name */
  3,                        /* shared memory and mmap are enabled */
  unixClose,                /* xClose method */
  unixLock,                 /* xLock method */
  unixUnlock,               /* xUnlock method */
  unixCheckReservedLock,    /* xCheckReservedLock method */
  unixShmMap                /* xShmMap method */
)
IOMETHODS(
  nolockIoFinder,           /* Finder function name */
  nolockIoMethods,          /* sqlite3_io_methods object name */
  3,                        /* shared memory is disabled */
  nolockClose,              /* xClose method */
  nolockLock,               /* xLock method */
  nolockUnlock,             /* xUnlock method */
  nolockCheckReservedLock,  /* xCheckReservedLock method */
  0                         /* xShmMap method */
)
IOMETHODS(
  dotlockIoFinder,          /* Finder function name */
  dotlockIoMethods,         /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  dotlockClose,             /* xClose method */
  dotlockLock,              /* xLock method */
  dotlockUnlock,            /* xUnlock method */
  dotlockCheckReservedLock, /* xCheckReservedLock method */
  0                         /* xShmMap method */
)

#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
IOMETHODS(
  flockIoFinder,            /* Finder function name */
  flockIoMethods,           /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  flockClose,               /* xClose method */
  flockLock,                /* xLock method */
  flockUnlock,              /* xUnlock method */
  flockCheckReservedLock,   /* xCheckReservedLock method */
  0                         /* xShmMap method */
)
#endif

#if OS_VXWORKS
IOMETHODS(
  semIoFinder,              /* Finder function name */
  semIoMethods,             /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  semClose,                 /* xClose method */
  semLock,                  /* xLock method */
  semUnlock,                /* xUnlock method */
  semCheckReservedLock,     /* xCheckReservedLock method */
  0                         /* xShmMap method */
)
#endif

#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
IOMETHODS(
  afpIoFinder,              /* Finder function name */
  afpIoMethods,             /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  afpClose,                 /* xClose method */
  afpLock,                  /* xLock method */
  afpUnlock,                /* xUnlock method */
  afpCheckReservedLock,     /* xCheckReservedLock method */
  0                         /* xShmMap method */
)
#endif

/*
** The proxy locking method is a "super-method" in the sense that it
** opens secondary file descriptors for the conch and lock files and
** it uses proxy, dot-file, AFP, and flock() locking methods on those
29776
29777
29778
29779
29780
29781
29782
29783

29784
29785
29786
29787
29788
29789
29790
29791
29792
29793
29794
29795
29796

29797
29798
29799
29800
29801
29802
29803
IOMETHODS(
  proxyIoFinder,            /* Finder function name */
  proxyIoMethods,           /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  proxyClose,               /* xClose method */
  proxyLock,                /* xLock method */
  proxyUnlock,              /* xUnlock method */
  proxyCheckReservedLock    /* xCheckReservedLock method */

)
#endif

/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
IOMETHODS(
  nfsIoFinder,               /* Finder function name */
  nfsIoMethods,              /* sqlite3_io_methods object name */
  1,                         /* shared memory is disabled */
  unixClose,                 /* xClose method */
  unixLock,                  /* xLock method */
  nfsUnlock,                 /* xUnlock method */
  unixCheckReservedLock      /* xCheckReservedLock method */

)
#endif

#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
/* 
** This "finder" function attempts to determine the best locking strategy 
** for the database file "filePath".  It then returns the sqlite3_io_methods







|
>












|
>







30119
30120
30121
30122
30123
30124
30125
30126
30127
30128
30129
30130
30131
30132
30133
30134
30135
30136
30137
30138
30139
30140
30141
30142
30143
30144
30145
30146
30147
30148
IOMETHODS(
  proxyIoFinder,            /* Finder function name */
  proxyIoMethods,           /* sqlite3_io_methods object name */
  1,                        /* shared memory is disabled */
  proxyClose,               /* xClose method */
  proxyLock,                /* xLock method */
  proxyUnlock,              /* xUnlock method */
  proxyCheckReservedLock,   /* xCheckReservedLock method */
  0                         /* xShmMap method */
)
#endif

/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
IOMETHODS(
  nfsIoFinder,               /* Finder function name */
  nfsIoMethods,              /* sqlite3_io_methods object name */
  1,                         /* shared memory is disabled */
  unixClose,                 /* xClose method */
  unixLock,                  /* xLock method */
  nfsUnlock,                 /* xUnlock method */
  unixCheckReservedLock,     /* xCheckReservedLock method */
  0                          /* xShmMap method */
)
#endif

#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
/* 
** This "finder" function attempts to determine the best locking strategy 
** for the database file "filePath".  It then returns the sqlite3_io_methods
32473
32474
32475
32476
32477
32478
32479





32480
32481
32482
32483
32484
32485
32486
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
#  error "WAL mode requires support from the Windows NT kernel, compile\
 with SQLITE_OMIT_WAL."
#endif






/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
#  define SQLITE_WIN32_HAS_ANSI
#endif







>
>
>
>
>







32818
32819
32820
32821
32822
32823
32824
32825
32826
32827
32828
32829
32830
32831
32832
32833
32834
32835
32836
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
#  error "WAL mode requires support from the Windows NT kernel, compile\
 with SQLITE_OMIT_WAL."
#endif

#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0
#  error "Memory mapped files require support from the Windows NT kernel,\
 compile with SQLITE_MAX_MMAP_SIZE=0."
#endif

/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
#  define SQLITE_WIN32_HAS_ANSI
#endif
32602
32603
32604
32605
32606
32607
32608
32609
32610
32611
32612

32613
32614
32615
32616
32617
32618
32619
*/
#ifndef winGetDirSep
#  define winGetDirSep()                '\\'
#endif

/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)

/*
** Two of the file mapping APIs are different under WinRT.  Figure out which
** set we need.
*/
#if SQLITE_OS_WINRT
WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
        LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);







|
|

|
>







32952
32953
32954
32955
32956
32957
32958
32959
32960
32961
32962
32963
32964
32965
32966
32967
32968
32969
32970
*/
#ifndef winGetDirSep
#  define winGetDirSep()                '\\'
#endif

/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode or memory mapped files (e.g. these APIs are available in the Windows
** CE SDK; however, they are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && \
        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
/*
** Two of the file mapping APIs are different under WinRT.  Figure out which
** set we need.
*/
#if SQLITE_OS_WINRT
WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
        LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
32633
32634
32635
32636
32637
32638
32639
32640
32641
32642
32643
32644
32645
32646
32647
WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */

/*
** This file mapping API is common to both Win32 and WinRT.
*/
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */

/*
** Some Microsoft compilers lack this definition.
*/
#ifndef INVALID_FILE_ATTRIBUTES
# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif







|







32984
32985
32986
32987
32988
32989
32990
32991
32992
32993
32994
32995
32996
32997
32998
WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */

/*
** This file mapping API is common to both Win32 and WinRT.
*/
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API */

/*
** Some Microsoft compilers lack this definition.
*/
#ifndef INVALID_FILE_ATTRIBUTES
# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
32926
32927
32928
32929
32930
32931
32932
32933
32934
32935
32936
32937
32938
32939
32940
32941
32942
32943
32944
32945
32946
32947
32948
32949
32950
  { "CreateFileW",             (SYSCALL)0,                       0 },
#endif

#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)

#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
        !defined(SQLITE_OMIT_WAL))
  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
#else
  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
#endif

#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)

#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
        !defined(SQLITE_OMIT_WAL))
  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
#else
  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
#endif

#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)







|









|







33277
33278
33279
33280
33281
33282
33283
33284
33285
33286
33287
33288
33289
33290
33291
33292
33293
33294
33295
33296
33297
33298
33299
33300
33301
  { "CreateFileW",             (SYSCALL)0,                       0 },
#endif

#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)

#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
#else
  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
#endif

#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)

#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
#else
  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
#endif

#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
33276
33277
33278
33279
33280
33281
33282
33283

33284
33285
33286
33287
33288
33289
33290
#endif

#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
        LPOVERLAPPED))aSyscall[48].pCurrent)
#endif

#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))

  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
#else
  { "MapViewOfFile",           (SYSCALL)0,                       0 },
#endif

#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        SIZE_T))aSyscall[49].pCurrent)







|
>







33627
33628
33629
33630
33631
33632
33633
33634
33635
33636
33637
33638
33639
33640
33641
33642
#endif

#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
        LPOVERLAPPED))aSyscall[48].pCurrent)
#endif

#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
#else
  { "MapViewOfFile",           (SYSCALL)0,                       0 },
#endif

#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        SIZE_T))aSyscall[49].pCurrent)
33346
33347
33348
33349
33350
33351
33352
33353
33354
33355
33356
33357
33358
33359
33360
#else
  { "UnlockFileEx",            (SYSCALL)0,                       0 },
#endif

#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        LPOVERLAPPED))aSyscall[58].pCurrent)

#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
#else
  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
#endif

#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)








|







33698
33699
33700
33701
33702
33703
33704
33705
33706
33707
33708
33709
33710
33711
33712
#else
  { "UnlockFileEx",            (SYSCALL)0,                       0 },
#endif

#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        LPOVERLAPPED))aSyscall[58].pCurrent)

#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
#else
  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
#endif

#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)

33382
33383
33384
33385
33386
33387
33388

33389



33390
33391
33392
33393
33394
33395
33396
#else
  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
#endif

#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
        DWORD))aSyscall[63].pCurrent)


  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },




#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
        BOOL))aSyscall[64].pCurrent)

#if SQLITE_OS_WINRT
  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
#else







>

>
>
>







33734
33735
33736
33737
33738
33739
33740
33741
33742
33743
33744
33745
33746
33747
33748
33749
33750
33751
33752
#else
  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
#endif

#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
        DWORD))aSyscall[63].pCurrent)

#if !SQLITE_OS_WINCE
  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
#else
  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
#endif

#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
        BOOL))aSyscall[64].pCurrent)

#if SQLITE_OS_WINRT
  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
#else
33405
33406
33407
33408
33409
33410
33411
33412
33413
33414
33415
33416
33417
33418
33419
#else
  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
#endif

#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)

#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
#else
  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
#endif

#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
        SIZE_T))aSyscall[67].pCurrent)







|







33761
33762
33763
33764
33765
33766
33767
33768
33769
33770
33771
33772
33773
33774
33775
#else
  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
#endif

#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)

#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
#else
  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
#endif

#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
        SIZE_T))aSyscall[67].pCurrent)
33469
33470
33471
33472
33473
33474
33475
33476
33477
33478
33479
33480
33481
33482
33483

#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)

  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },

#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)

#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
#endif

#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)







|







33825
33826
33827
33828
33829
33830
33831
33832
33833
33834
33835
33836
33837
33838
33839

#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)

  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },

#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)

#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
#endif

#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
33725
33726
33727
33728
33729
33730
33731
33732

33733
33734
33735
33736
33737
33738
33739
  assert( sleepObj!=NULL );
  osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
#else
  osSleep(milliseconds);
#endif
}

#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0

SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
  DWORD rc;
  while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
                                       TRUE))==WAIT_IO_COMPLETION ){}
  return rc;
}
#endif







|
>







34081
34082
34083
34084
34085
34086
34087
34088
34089
34090
34091
34092
34093
34094
34095
34096
  assert( sleepObj!=NULL );
  osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
#else
  osSleep(milliseconds);
#endif
}

#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
        SQLITE_THREADSAFE>0
SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
  DWORD rc;
  while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
                                       TRUE))==WAIT_IO_COMPLETION ){}
  return rc;
}
#endif
39044
39045
39046
39047
39048
39049
39050







39051
39052
39053
39054
39055
39056
39057
/*
** Free up as much memory as possible from the page cache.
*/
SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
  assert( pCache->pCache!=0 );
  sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
}








#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
** callback. This is only used if the SQLITE_CHECK_PAGES macro is
** defined.
*/







>
>
>
>
>
>
>







39401
39402
39403
39404
39405
39406
39407
39408
39409
39410
39411
39412
39413
39414
39415
39416
39417
39418
39419
39420
39421
/*
** Free up as much memory as possible from the page cache.
*/
SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
  assert( pCache->pCache!=0 );
  sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
}

/*
** Return the size of the header added by this middleware layer
** in the page-cache hierarchy.
*/
SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return sizeof(PgHdr); }


#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
** callback. This is only used if the SQLITE_CHECK_PAGES macro is
** defined.
*/
39750
39751
39752
39753
39754
39755
39756
39757
39758
39759
39760
39761
39762
39763
39764
  assert( pCache->nPage >= pCache->nRecyclable );
  nPinned = pCache->nPage - pCache->nRecyclable;
  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
  assert( pCache->n90pct == pCache->nMax*9/10 );
  if( createFlag==1 && (
        nPinned>=pGroup->mxPinned
     || nPinned>=pCache->n90pct
     || pcache1UnderMemoryPressure(pCache)
  )){
    return 0;
  }

  if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
  assert( pCache->nHash>0 && pCache->apHash );








|







40114
40115
40116
40117
40118
40119
40120
40121
40122
40123
40124
40125
40126
40127
40128
  assert( pCache->nPage >= pCache->nRecyclable );
  nPinned = pCache->nPage - pCache->nRecyclable;
  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
  assert( pCache->n90pct == pCache->nMax*9/10 );
  if( createFlag==1 && (
        nPinned>=pGroup->mxPinned
     || nPinned>=pCache->n90pct
     || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
  )){
    return 0;
  }

  if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
  assert( pCache->nHash>0 && pCache->apHash );

40043
40044
40045
40046
40047
40048
40049





40050
40051
40052
40053
40054
40055
40056
    pcache1Truncate,         /* xTruncate */
    pcache1Destroy,          /* xDestroy */
    pcache1Shrink            /* xShrink */
  };
  sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
}






#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
** held by the pager system. Memory in use by any SQLite pager allocated
** by the current thread may be sqlite3_free()ed.
**
** nReq is the number of bytes of memory required. Once this much has







>
>
>
>
>







40407
40408
40409
40410
40411
40412
40413
40414
40415
40416
40417
40418
40419
40420
40421
40422
40423
40424
40425
    pcache1Truncate,         /* xTruncate */
    pcache1Destroy,          /* xDestroy */
    pcache1Shrink            /* xShrink */
  };
  sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
}

/*
** Return the size of the header on each page of this PCACHE implementation.
*/
SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return sizeof(PgHdr1); }

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
** held by the pager system. Memory in use by any SQLite pager allocated
** by the current thread may be sqlite3_free()ed.
**
** nReq is the number of bytes of memory required. Once this much has
42694
42695
42696
42697
42698
42699
42700








42701
42702
42703
42704
42705
42706
42707
      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
      sqlite3OsClose(pPager->jfd);
    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
      if( pPager->journalOff==0 ){
        rc = SQLITE_OK;
      }else{
        rc = sqlite3OsTruncate(pPager->jfd, 0);








      }
      pPager->journalOff = 0;
    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
    ){
      rc = zeroJournalHdr(pPager, hasMaster);
      pPager->journalOff = 0;







>
>
>
>
>
>
>
>







43063
43064
43065
43066
43067
43068
43069
43070
43071
43072
43073
43074
43075
43076
43077
43078
43079
43080
43081
43082
43083
43084
      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
      sqlite3OsClose(pPager->jfd);
    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
      if( pPager->journalOff==0 ){
        rc = SQLITE_OK;
      }else{
        rc = sqlite3OsTruncate(pPager->jfd, 0);
        if( rc==SQLITE_OK && pPager->fullSync ){
          /* Make sure the new file size is written into the inode right away.
          ** Otherwise the journal might resurrect following a power loss and
          ** cause the last transaction to roll back.  See
          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
          */
          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
        }
      }
      pPager->journalOff = 0;
    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
    ){
      rc = zeroJournalHdr(pPager, hasMaster);
      pPager->journalOff = 0;
43644
43645
43646
43647
43648
43649
43650
43651
43652
43653
43654
43655
43656
43657
43658
      ** of bytes 24..39 of the database.  Bytes 28..31 should always be
      ** zero or the size of the database in page. Bytes 32..35 and 35..39
      ** should be page numbers which are never 0xffffffff.  So filling
      ** pPager->dbFileVers[] with all 0xff bytes should suffice.
      **
      ** For an encrypted database, the situation is more complex:  bytes
      ** 24..39 of the database are white noise.  But the probability of
      ** white noising equaling 16 bytes of 0xff is vanishingly small so
      ** we should still be ok.
      */
      memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
    }else{
      u8 *dbFileVers = &((u8*)pPg->pData)[24];
      memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
    }







|







44021
44022
44023
44024
44025
44026
44027
44028
44029
44030
44031
44032
44033
44034
44035
      ** of bytes 24..39 of the database.  Bytes 28..31 should always be
      ** zero or the size of the database in page. Bytes 32..35 and 35..39
      ** should be page numbers which are never 0xffffffff.  So filling
      ** pPager->dbFileVers[] with all 0xff bytes should suffice.
      **
      ** For an encrypted database, the situation is more complex:  bytes
      ** 24..39 of the database are white noise.  But the probability of
      ** white noise equaling 16 bytes of 0xff is vanishingly small so
      ** we should still be ok.
      */
      memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
    }else{
      u8 *dbFileVers = &((u8*)pPg->pData)[24];
      memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
    }
44371
44372
44373
44374
44375
44376
44377
44378
44379
44380
44381
44382


44383
44384


44385
44386
44387
44388
44389
44390
44391
    if( rc==SQLITE_OK ){
      pNew = (char *)sqlite3PageMalloc(pageSize);
      if( !pNew ) rc = SQLITE_NOMEM;
    }

    if( rc==SQLITE_OK ){
      pager_reset(pPager);
      sqlite3PageFree(pPager->pTmpSpace);
      pPager->pTmpSpace = pNew;
      rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
    }
    if( rc==SQLITE_OK ){


      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
      pPager->pageSize = pageSize;


    }
  }

  *pPageSize = pPager->pageSize;
  if( rc==SQLITE_OK ){
    if( nReserve<0 ) nReserve = pPager->nReserve;
    assert( nReserve>=0 && nReserve<1000 );







<
<



>
>


>
>







44748
44749
44750
44751
44752
44753
44754


44755
44756
44757
44758
44759
44760
44761
44762
44763
44764
44765
44766
44767
44768
44769
44770
    if( rc==SQLITE_OK ){
      pNew = (char *)sqlite3PageMalloc(pageSize);
      if( !pNew ) rc = SQLITE_NOMEM;
    }

    if( rc==SQLITE_OK ){
      pager_reset(pPager);


      rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
    }
    if( rc==SQLITE_OK ){
      sqlite3PageFree(pPager->pTmpSpace);
      pPager->pTmpSpace = pNew;
      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
      pPager->pageSize = pageSize;
    }else{
      sqlite3PageFree(pNew);
    }
  }

  *pPageSize = pPager->pageSize;
  if( rc==SQLITE_OK ){
    if( nReserve<0 ) nReserve = pPager->nReserve;
    assert( nReserve>=0 && nReserve<1000 );
47589
47590
47591
47592
47593
47594
47595












47596
47597
47598
47599
47600
47601
47602
    sqlite3PcacheMakeDirty(pPgHdr);
    sqlite3PagerUnrefNotNull(pPgHdr);
  }

  return SQLITE_OK;
}
#endif













/*
** Return a pointer to the data for the specified page.
*/
SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
  assert( pPg->nRef>0 || pPg->pPager->memDb );
  return pPg->pData;







>
>
>
>
>
>
>
>
>
>
>
>







47968
47969
47970
47971
47972
47973
47974
47975
47976
47977
47978
47979
47980
47981
47982
47983
47984
47985
47986
47987
47988
47989
47990
47991
47992
47993
    sqlite3PcacheMakeDirty(pPgHdr);
    sqlite3PagerUnrefNotNull(pPgHdr);
  }

  return SQLITE_OK;
}
#endif

/*
** The page handle passed as the first argument refers to a dirty page 
** with a page number other than iNew. This function changes the page's 
** page number to iNew and sets the value of the PgHdr.flags field to 
** the value passed as the third parameter.
*/
SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
  assert( pPg->pgno!=iNew );
  pPg->flags = flags;
  sqlite3PcacheMove(pPg, iNew);
}

/*
** Return a pointer to the data for the specified page.
*/
SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
  assert( pPg->nRef>0 || pPg->pPager->memDb );
  return pPg->pData;
47987
47988
47989
47990
47991
47992
47993

47994
47995
47996
47997
47998
47999
48000
** is empty, return 0.
*/
SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
  assert( pPager->eState>=PAGER_READER );
  return sqlite3WalFramesize(pPager->pWal);
}
#endif


#endif /* SQLITE_OMIT_DISKIO */

/************** End of pager.c ***********************************************/
/************** Begin file wal.c *********************************************/
/*
** 2010 February 1







>







48378
48379
48380
48381
48382
48383
48384
48385
48386
48387
48388
48389
48390
48391
48392
** is empty, return 0.
*/
SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
  assert( pPager->eState>=PAGER_READER );
  return sqlite3WalFramesize(pPager->pWal);
}
#endif


#endif /* SQLITE_OMIT_DISKIO */

/************** End of pager.c ***********************************************/
/************** Begin file wal.c *********************************************/
/*
** 2010 February 1
49497
49498
49499
49500
49501
49502
49503
49504
49505
49506
49507
49508
49509
49510
49511
#endif
}

/* 
** Free an iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){
  sqlite3ScratchFree(p);
}

/*
** Construct a WalInterator object that can be used to loop over all 
** pages in the WAL in ascending order. The caller must hold the checkpoint
** lock.
**







|







49889
49890
49891
49892
49893
49894
49895
49896
49897
49898
49899
49900
49901
49902
49903
#endif
}

/* 
** Free an iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){
  sqlite3_free(p);
}

/*
** Construct a WalInterator object that can be used to loop over all 
** pages in the WAL in ascending order. The caller must hold the checkpoint
** lock.
**
49532
49533
49534
49535
49536
49537
49538
49539
49540
49541
49542
49543
49544
49545
49546
49547
49548
49549
49550
49551
49552
49553
49554
49555
49556
  iLast = pWal->hdr.mxFrame;

  /* Allocate space for the WalIterator object. */
  nSegment = walFramePage(iLast) + 1;
  nByte = sizeof(WalIterator) 
        + (nSegment-1)*sizeof(struct WalSegment)
        + iLast*sizeof(ht_slot);
  p = (WalIterator *)sqlite3ScratchMalloc(nByte);
  if( !p ){
    return SQLITE_NOMEM;
  }
  memset(p, 0, nByte);
  p->nSegment = nSegment;

  /* Allocate temporary space used by the merge-sort routine. This block
  ** of memory will be freed before this function returns.
  */
  aTmp = (ht_slot *)sqlite3ScratchMalloc(
      sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
  );
  if( !aTmp ){
    rc = SQLITE_NOMEM;
  }

  for(i=0; rc==SQLITE_OK && i<nSegment; i++){







|









|







49924
49925
49926
49927
49928
49929
49930
49931
49932
49933
49934
49935
49936
49937
49938
49939
49940
49941
49942
49943
49944
49945
49946
49947
49948
  iLast = pWal->hdr.mxFrame;

  /* Allocate space for the WalIterator object. */
  nSegment = walFramePage(iLast) + 1;
  nByte = sizeof(WalIterator) 
        + (nSegment-1)*sizeof(struct WalSegment)
        + iLast*sizeof(ht_slot);
  p = (WalIterator *)sqlite3_malloc(nByte);
  if( !p ){
    return SQLITE_NOMEM;
  }
  memset(p, 0, nByte);
  p->nSegment = nSegment;

  /* Allocate temporary space used by the merge-sort routine. This block
  ** of memory will be freed before this function returns.
  */
  aTmp = (ht_slot *)sqlite3_malloc(
      sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
  );
  if( !aTmp ){
    rc = SQLITE_NOMEM;
  }

  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
49579
49580
49581
49582
49583
49584
49585
49586
49587
49588
49589
49590
49591
49592
49593
      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
      p->aSegment[i].iZero = iZero;
      p->aSegment[i].nEntry = nEntry;
      p->aSegment[i].aIndex = aIndex;
      p->aSegment[i].aPgno = (u32 *)aPgno;
    }
  }
  sqlite3ScratchFree(aTmp);

  if( rc!=SQLITE_OK ){
    walIteratorFree(p);
  }
  *pp = p;
  return rc;
}







|







49971
49972
49973
49974
49975
49976
49977
49978
49979
49980
49981
49982
49983
49984
49985
      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
      p->aSegment[i].iZero = iZero;
      p->aSegment[i].nEntry = nEntry;
      p->aSegment[i].aIndex = aIndex;
      p->aSegment[i].aPgno = (u32 *)aPgno;
    }
  }
  sqlite3_free(aTmp);

  if( rc!=SQLITE_OK ){
    walIteratorFree(p);
  }
  *pp = p;
  return rc;
}
50518
50519
50520
50521
50522
50523
50524
50525
50526
50527
50528
50529
50530
50531
50532
      ** committed. As a result, the call to xUndo may not fail.
      */
      assert( walFramePgno(pWal, iFrame)!=1 );
      rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
    }
    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
  }
  assert( rc==SQLITE_OK );
  return rc;
}

/* 
** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 
** values. This function populates the array with values required to 
** "rollback" the write position of the WAL handle back to the current 







<







50910
50911
50912
50913
50914
50915
50916

50917
50918
50919
50920
50921
50922
50923
      ** committed. As a result, the call to xUndo may not fail.
      */
      assert( walFramePgno(pWal, iFrame)!=1 );
      rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
    }
    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
  }

  return rc;
}

/* 
** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 
** values. This function populates the array with values required to 
** "rollback" the write position of the WAL handle back to the current 
51381
51382
51383
51384
51385
51386
51387
51388


51389
51390
51391
51392
51393
51394
51395
51396
51397
**
** Access to all fields of this structure is controlled by the mutex
** stored in MemPage.pBt->mutex.
*/
struct MemPage {
  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
  u8 intKey;           /* True if intkey flag is set */


  u8 leaf;             /* True if leaf flag is set */
  u8 hasData;          /* True if this page stores data */
  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
  u8 max1bytePayload;  /* min(maxLocal,127) */
  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
  u16 cellOffset;      /* Index in aData of first cell pointer */
  u16 nFree;           /* Number of free bytes on the page */







|
>
>
|
<







51772
51773
51774
51775
51776
51777
51778
51779
51780
51781
51782

51783
51784
51785
51786
51787
51788
51789
**
** Access to all fields of this structure is controlled by the mutex
** stored in MemPage.pBt->mutex.
*/
struct MemPage {
  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
  u8 intKey;           /* True if table b-trees.  False for index b-trees */
  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
  u8 noPayload;        /* True if internal intKey page (thus w/o data) */
  u8 leaf;             /* True if a leaf page */

  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
  u8 max1bytePayload;  /* min(maxLocal,127) */
  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
  u16 cellOffset;      /* Index in aData of first cell pointer */
  u16 nFree;           /* Number of free bytes on the page */
51543
51544
51545
51546
51547
51548
51549
51550
51551
51552
51553
51554
51555
51556
51557
51558
51559
51560
51561
51562
51563
51564
51565
51566
51567
51568
51569
51570
51571
51572
51573
51574
51575
51576
51577
51578
51579
51580
51581
51582
51583
  Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nRef;             /* Number of references to this structure */
  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
  BtLock *pLock;        /* List of locks held on this shared-btree struct */
  Btree *pWriter;       /* Btree with currently open write transaction */
#endif
  u8 *pTmpSpace;        /* BtShared.pageSize bytes of space for tmp use */
};

/*
** Allowed values for BtShared.btsFlags
*/
#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
#define BTS_SECURE_DELETE    0x0004   /* PRAGMA secure_delete is enabled */
#define BTS_INITIALLY_EMPTY  0x0008   /* Database was empty at trans start */
#define BTS_NO_WAL           0x0010   /* Do not open write-ahead-log files */
#define BTS_EXCLUSIVE        0x0020   /* pWriter has an exclusive lock */
#define BTS_PENDING          0x0040   /* Waiting for read-locks to clear */

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
*/
typedef struct CellInfo CellInfo;
struct CellInfo {
  i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
  u8 *pCell;     /* Pointer to the start of cell content */
  u32 nData;     /* Number of bytes of data */
  u32 nPayload;  /* Total amount of payload */
  u16 nHeader;   /* Size of the cell content header in bytes */
  u16 nLocal;    /* Amount of payload held locally */
  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
  u16 nSize;     /* Size of the cell content on the main b-tree page */
};

/*
** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
** this will be declared corrupt. This value is calculated based on a







|




















|
|
<
|
<
|







51935
51936
51937
51938
51939
51940
51941
51942
51943
51944
51945
51946
51947
51948
51949
51950
51951
51952
51953
51954
51955
51956
51957
51958
51959
51960
51961
51962
51963
51964

51965

51966
51967
51968
51969
51970
51971
51972
51973
  Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nRef;             /* Number of references to this structure */
  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
  BtLock *pLock;        /* List of locks held on this shared-btree struct */
  Btree *pWriter;       /* Btree with currently open write transaction */
#endif
  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
};

/*
** Allowed values for BtShared.btsFlags
*/
#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
#define BTS_SECURE_DELETE    0x0004   /* PRAGMA secure_delete is enabled */
#define BTS_INITIALLY_EMPTY  0x0008   /* Database was empty at trans start */
#define BTS_NO_WAL           0x0010   /* Do not open write-ahead-log files */
#define BTS_EXCLUSIVE        0x0020   /* pWriter has an exclusive lock */
#define BTS_PENDING          0x0040   /* Waiting for read-locks to clear */

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
*/
typedef struct CellInfo CellInfo;
struct CellInfo {
  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
  u8 *pPayload;  /* Pointer to the start of payload */

  u32 nPayload;  /* Bytes of payload */

  u16 nLocal;    /* Amount of payload held locally, not on overflow */
  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
  u16 nSize;     /* Size of the cell content on the main b-tree page */
};

/*
** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
** this will be declared corrupt. This value is calculated based on a
51598
51599
51600
51601
51602
51603
51604





51605
51606
51607
51608
51609
51610
51611
51612
51613
51614
51615
51616
51617

51618
51619
51620
51621
51622
51623
51624
**
** A single database file can be shared by two more database connections,
** but cursors cannot be shared.  Each cursor is associated with a
** particular database connection identified BtCursor.pBtree.db.
**
** Fields in this structure are accessed under the BtShared.mutex
** found at self->pBt->mutex. 





*/
struct BtCursor {
  Btree *pBtree;            /* The Btree to which this cursor belongs */
  BtShared *pBt;            /* The BtShared this cursor points to */
  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
  Pgno *aOverflow;          /* Cache of overflow page locations */
  CellInfo info;            /* A parse of the cell we are pointing at */
  i64 nKey;                 /* Size of pKey, or last integer key */
  void *pKey;               /* Saved key that was cursor last known position */
  Pgno pgnoRoot;            /* The root page of this tree */
  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive */

  u8 curFlags;              /* zero or more BTCF_* flags defined below */
  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
  u8 hints;                             /* As configured by CursorSetHints() */
  i16 iPage;                            /* Index of current page in apPage */
  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
  MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
};







>
>
>
>
>












|
>







51988
51989
51990
51991
51992
51993
51994
51995
51996
51997
51998
51999
52000
52001
52002
52003
52004
52005
52006
52007
52008
52009
52010
52011
52012
52013
52014
52015
52016
52017
52018
52019
52020
**
** A single database file can be shared by two more database connections,
** but cursors cannot be shared.  Each cursor is associated with a
** particular database connection identified BtCursor.pBtree.db.
**
** Fields in this structure are accessed under the BtShared.mutex
** found at self->pBt->mutex. 
**
** skipNext meaning:
**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
**    eState==FAULT:                   Cursor fault with skipNext as error code.
*/
struct BtCursor {
  Btree *pBtree;            /* The Btree to which this cursor belongs */
  BtShared *pBt;            /* The BtShared this cursor points to */
  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
  Pgno *aOverflow;          /* Cache of overflow page locations */
  CellInfo info;            /* A parse of the cell we are pointing at */
  i64 nKey;                 /* Size of pKey, or last integer key */
  void *pKey;               /* Saved key that was cursor last known position */
  Pgno pgnoRoot;            /* The root page of this tree */
  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
                   ** Error code if eState==CURSOR_FAULT */
  u8 curFlags;              /* zero or more BTCF_* flags defined below */
  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
  u8 hints;                             /* As configured by CursorSetHints() */
  i16 iPage;                            /* Index of current page in apPage */
  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
  MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
};
51656
51657
51658
51659
51660
51661
51662
51663
51664
51665
51666
51667
51668
51669
51670
**   seek the cursor to the saved position.
**
** CURSOR_FAULT:
**   An unrecoverable error (an I/O error or a malloc failure) has occurred
**   on a different connection that shares the BtShared cache with this
**   cursor.  The error has left the cache in an inconsistent state.
**   Do nothing else with this cursor.  Any attempt to use the cursor
**   should return the error code stored in BtCursor.skip
*/
#define CURSOR_INVALID           0
#define CURSOR_VALID             1
#define CURSOR_SKIPNEXT          2
#define CURSOR_REQUIRESEEK       3
#define CURSOR_FAULT             4








|







52052
52053
52054
52055
52056
52057
52058
52059
52060
52061
52062
52063
52064
52065
52066
**   seek the cursor to the saved position.
**
** CURSOR_FAULT:
**   An unrecoverable error (an I/O error or a malloc failure) has occurred
**   on a different connection that shares the BtShared cache with this
**   cursor.  The error has left the cache in an inconsistent state.
**   Do nothing else with this cursor.  Any attempt to use the cursor
**   should return the error code stored in BtCursor.skipNext
*/
#define CURSOR_INVALID           0
#define CURSOR_VALID             1
#define CURSOR_SKIPNEXT          2
#define CURSOR_REQUIRESEEK       3
#define CURSOR_FAULT             4

51766
51767
51768
51769
51770
51771
51772


51773
51774
51775
51776
51777
51778
51779
  BtShared *pBt;    /* The tree being checked out */
  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
  Pgno nPage;       /* Number of pages in the database */
  int mxErr;        /* Stop accumulating errors when this reaches zero */
  int nErr;         /* Number of messages written to zErrMsg so far */
  int mallocFailed; /* A memory allocation error has occurred */


  StrAccum errMsg;  /* Accumulate the error message text here */
};

/*
** Routines to read or write a two- and four-byte big-endian integer values.
*/
#define get2byte(x)   ((x)[0]<<8 | (x)[1])







>
>







52162
52163
52164
52165
52166
52167
52168
52169
52170
52171
52172
52173
52174
52175
52176
52177
  BtShared *pBt;    /* The tree being checked out */
  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
  Pgno nPage;       /* Number of pages in the database */
  int mxErr;        /* Stop accumulating errors when this reaches zero */
  int nErr;         /* Number of messages written to zErrMsg so far */
  int mallocFailed; /* A memory allocation error has occurred */
  const char *zPfx; /* Error message prefix */
  int v1, v2;       /* Values for up to two %d fields in zPfx */
  StrAccum errMsg;  /* Accumulate the error message text here */
};

/*
** Routines to read or write a two- and four-byte big-endian integer values.
*/
#define get2byte(x)   ((x)[0]<<8 | (x)[1])
52552
52553
52554
52555
52556
52557
52558
52559


52560
52561
52562
52563
52564
52565
52566
  i64 iRow,               /* The rowid that might be changing */
  int isClearTable        /* True if all rows are being deleted */
){
  BtCursor *p;
  BtShared *pBt = pBtree->pBt;
  assert( sqlite3BtreeHoldsMutex(pBtree) );
  for(p=pBt->pCursor; p; p=p->pNext){
    if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){


      p->eState = CURSOR_INVALID;
    }
  }
}

#else
  /* Stub function when INCRBLOB is omitted */







|
>
>







52950
52951
52952
52953
52954
52955
52956
52957
52958
52959
52960
52961
52962
52963
52964
52965
52966
  i64 iRow,               /* The rowid that might be changing */
  int isClearTable        /* True if all rows are being deleted */
){
  BtCursor *p;
  BtShared *pBt = pBtree->pBt;
  assert( sqlite3BtreeHoldsMutex(pBtree) );
  for(p=pBt->pCursor; p; p=p->pNext){
    if( (p->curFlags & BTCF_Incrblob)!=0
     && (isClearTable || p->info.nKey==iRow)
    ){
      p->eState = CURSOR_INVALID;
    }
  }
}

#else
  /* Stub function when INCRBLOB is omitted */
52725
52726
52727
52728
52729
52730
52731
52732
52733
52734
52735
52736
52737
52738
52739
52740
52741

/* This helper routine to saveAllCursors does the actual work of saving
** the cursors if and when a cursor is found that actually requires saving.
** The common case is that no cursors need to be saved, so this routine is
** broken out from its caller to avoid unnecessary stack pointer movement.
*/
static int SQLITE_NOINLINE saveCursorsOnList(
  BtCursor *p,           /* The first cursor that needs saving */
  Pgno iRoot,            /* Only save cursor with this iRoot.  Save all if zero */
  BtCursor *pExcept      /* Do not save this cursor */
){
  do{
    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
      if( p->eState==CURSOR_VALID ){
        int rc = saveCursorPosition(p);
        if( SQLITE_OK!=rc ){
          return rc;







|
|
|







53125
53126
53127
53128
53129
53130
53131
53132
53133
53134
53135
53136
53137
53138
53139
53140
53141

/* This helper routine to saveAllCursors does the actual work of saving
** the cursors if and when a cursor is found that actually requires saving.
** The common case is that no cursors need to be saved, so this routine is
** broken out from its caller to avoid unnecessary stack pointer movement.
*/
static int SQLITE_NOINLINE saveCursorsOnList(
  BtCursor *p,         /* The first cursor that needs saving */
  Pgno iRoot,          /* Only save cursor with this iRoot. Save all if zero */
  BtCursor *pExcept    /* Do not save this cursor */
){
  do{
    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
      if( p->eState==CURSOR_VALID ){
        int rc = saveCursorPosition(p);
        if( SQLITE_OK!=rc ){
          return rc;
52839
52840
52841
52842
52843
52844
52845
52846
52847
52848
52849
52850
52851
52852
52853
**
** Calling this routine with a NULL cursor pointer returns false.
**
** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
** back to where it ought to be if this routine returns true.
*/
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
  return pCur && pCur->eState!=CURSOR_VALID;
}

/*
** This routine restores a cursor back to its original position after it
** has been moved by some outside activity (such as a btree rebalance or
** a row having been deleted out from under the cursor).  
**







|







53239
53240
53241
53242
53243
53244
53245
53246
53247
53248
53249
53250
53251
53252
53253
**
** Calling this routine with a NULL cursor pointer returns false.
**
** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
** back to where it ought to be if this routine returns true.
*/
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
  return pCur->eState!=CURSOR_VALID;
}

/*
** This routine restores a cursor back to its original position after it
** has been moved by some outside activity (such as a btree rebalance or
** a row having been deleted out from under the cursor).  
**
53033
53034
53035
53036
53037
53038
53039
53040
53041
53042
53043
53044
53045
53046
53047
53048
53049
53050
53051
53052
53053
53054
53055
53056
53057
53058
53059
53060
53061

53062


53063
53064
53065
53066


53067
53068
53069
53070
53071
53072
53073
53074
53075
53076
53077
53078
53079

53080
53081
53082
53083
53084
53085
53086
53087
}

/*
** Parse a cell content block and fill in the CellInfo structure.  There
** are two versions of this function.  btreeParseCell() takes a 
** cell index as the second argument and btreeParseCellPtr() 
** takes a pointer to the body of the cell as its second argument.
**
** Within this file, the parseCell() macro can be called instead of
** btreeParseCellPtr(). Using some compilers, this will be faster.
*/
static void btreeParseCellPtr(
  MemPage *pPage,         /* Page containing the cell */
  u8 *pCell,              /* Pointer to the cell text. */
  CellInfo *pInfo         /* Fill in this structure */
){
  u16 n;                  /* Number bytes in cell content header */
  u32 nPayload;           /* Number of bytes of cell payload */

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );

  pInfo->pCell = pCell;
  assert( pPage->leaf==0 || pPage->leaf==1 );
  n = pPage->childPtrSize;
  assert( n==4-4*pPage->leaf );
  if( pPage->intKey ){
    if( pPage->hasData ){
      assert( n==0 );
      n = getVarint32(pCell, nPayload);

    }else{


      nPayload = 0;
    }
    n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
    pInfo->nData = nPayload;


  }else{
    pInfo->nData = 0;
    n += getVarint32(&pCell[n], nPayload);
    pInfo->nKey = nPayload;
  }
  pInfo->nPayload = nPayload;
  pInfo->nHeader = n;
  testcase( nPayload==pPage->maxLocal );
  testcase( nPayload==pPage->maxLocal+1 );
  if( likely(nPayload<=pPage->maxLocal) ){
    /* This is the (easy) common case where the entire payload fits
    ** on the local page.  No overflow is required.
    */

    if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4;
    pInfo->nLocal = (u16)nPayload;
    pInfo->iOverflow = 0;
  }else{
    /* If the payload will not fit completely on the local page, we have
    ** to decide how much to store locally and how much to spill onto
    ** overflow pages.  The strategy is to minimize the amount of unused
    ** space on overflow pages while keeping the amount of local storage







<
<
<






|



<
<

<
<
|
<
|
|
>
|
>
>
|
<
|
|
>
>

|
|



|


|



>
|







53433
53434
53435
53436
53437
53438
53439



53440
53441
53442
53443
53444
53445
53446
53447
53448
53449


53450


53451

53452
53453
53454
53455
53456
53457
53458

53459
53460
53461
53462
53463
53464
53465
53466
53467
53468
53469
53470
53471
53472
53473
53474
53475
53476
53477
53478
53479
53480
53481
53482
53483
53484
}

/*
** Parse a cell content block and fill in the CellInfo structure.  There
** are two versions of this function.  btreeParseCell() takes a 
** cell index as the second argument and btreeParseCellPtr() 
** takes a pointer to the body of the cell as its second argument.



*/
static void btreeParseCellPtr(
  MemPage *pPage,         /* Page containing the cell */
  u8 *pCell,              /* Pointer to the cell text. */
  CellInfo *pInfo         /* Fill in this structure */
){
  u8 *pIter;              /* For scanning through pCell */
  u32 nPayload;           /* Number of bytes of cell payload */

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );


  assert( pPage->leaf==0 || pPage->leaf==1 );


  if( pPage->intKeyLeaf ){

    assert( pPage->childPtrSize==0 );
    pIter = pCell + getVarint32(pCell, nPayload);
    pIter += getVarint(pIter, (u64*)&pInfo->nKey);
  }else if( pPage->noPayload ){
    assert( pPage->childPtrSize==4 );
    pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
    pInfo->nPayload = 0;

    pInfo->nLocal = 0;
    pInfo->iOverflow = 0;
    pInfo->pPayload = 0;
    return;
  }else{
    pIter = pCell + pPage->childPtrSize;
    pIter += getVarint32(pIter, nPayload);
    pInfo->nKey = nPayload;
  }
  pInfo->nPayload = nPayload;
  pInfo->pPayload = pIter;
  testcase( nPayload==pPage->maxLocal );
  testcase( nPayload==pPage->maxLocal+1 );
  if( nPayload<=pPage->maxLocal ){
    /* This is the (easy) common case where the entire payload fits
    ** on the local page.  No overflow is required.
    */
    pInfo->nSize = nPayload + (u16)(pIter - pCell);
    if( pInfo->nSize<4 ) pInfo->nSize = 4;
    pInfo->nLocal = (u16)nPayload;
    pInfo->iOverflow = 0;
  }else{
    /* If the payload will not fit completely on the local page, we have
    ** to decide how much to store locally and how much to spill onto
    ** overflow pages.  The strategy is to minimize the amount of unused
    ** space on overflow pages while keeping the amount of local storage
53100
53101
53102
53103
53104
53105
53106
53107
53108
53109
53110
53111
53112
53113
53114
53115
53116
53117
53118
53119
53120
53121
53122
53123
53124
53125
53126
53127
53128

53129
53130
53131
53132
53133
53134
53135
53136
53137
53138
53139
53140
53141

53142
53143

53144


53145



53146
53147

53148
53149
53150
53151
53152
53153
53154
53155
53156
53157
53158
53159



53160
53161
53162
53163
53164
53165
53166
53167
53168
53169
53170
53171
53172
53173
53174
53175
53176
53177
53178
53179
53180
53181
53182
53183
    testcase( surplus==maxLocal );
    testcase( surplus==maxLocal+1 );
    if( surplus <= maxLocal ){
      pInfo->nLocal = (u16)surplus;
    }else{
      pInfo->nLocal = (u16)minLocal;
    }
    pInfo->iOverflow = (u16)(pInfo->nLocal + n);
    pInfo->nSize = pInfo->iOverflow + 4;
  }
}
#define parseCell(pPage, iCell, pInfo) \
  btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
static void btreeParseCell(
  MemPage *pPage,         /* Page containing the cell */
  int iCell,              /* The cell index.  First cell is 0 */
  CellInfo *pInfo         /* Fill in this structure */
){
  parseCell(pPage, iCell, pInfo);
}

/*
** Compute the total number of bytes that a Cell needs in the cell
** data area of the btree-page.  The return number includes the cell
** data header and the local payload, but not any overflow page or
** the space used by the cell pointer.
*/
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
  u8 *pIter = &pCell[pPage->childPtrSize];

  u32 nSize;

#ifdef SQLITE_DEBUG
  /* The value returned by this function should always be the same as
  ** the (CellInfo.nSize) value found by doing a full parse of the
  ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
  ** this function verifies that this invariant is not violated. */
  CellInfo debuginfo;
  btreeParseCellPtr(pPage, pCell, &debuginfo);
#endif

  if( pPage->intKey ){
    u8 *pEnd;

    if( pPage->hasData ){
      pIter += getVarint32(pIter, nSize);

    }else{


      nSize = 0;



    }


    /* pIter now points at the 64-bit integer key value, a variable length 
    ** integer. The following block moves pIter to point at the first byte
    ** past the end of the key value. */
    pEnd = &pIter[9];
    while( (*pIter++)&0x80 && pIter<pEnd );
  }else{
    pIter += getVarint32(pIter, nSize);
  }

  testcase( nSize==pPage->maxLocal );
  testcase( nSize==pPage->maxLocal+1 );
  if( nSize>pPage->maxLocal ){



    int minLocal = pPage->minLocal;
    nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
    testcase( nSize==pPage->maxLocal );
    testcase( nSize==pPage->maxLocal+1 );
    if( nSize>pPage->maxLocal ){
      nSize = minLocal;
    }
    nSize += 4;
  }
  nSize += (u32)(pIter - pCell);

  /* The minimum size of any cell is 4 bytes. */
  if( nSize<4 ){
    nSize = 4;
  }

  assert( nSize==debuginfo.nSize );
  return (u16)nSize;
}

#ifdef SQLITE_DEBUG
/* This variation on cellSizePtr() is used inside of assert() statements
** only. */
static u16 cellSize(MemPage *pPage, int iCell){







|



<
<





|









|
>
|










|
|
>
|
|
>
|
>
>
|
>
>
>
|
|
>





<
<

<


|
>
>
>







|

<
<
<
<
<
<
<
|







53497
53498
53499
53500
53501
53502
53503
53504
53505
53506
53507


53508
53509
53510
53511
53512
53513
53514
53515
53516
53517
53518
53519
53520
53521
53522
53523
53524
53525
53526
53527
53528
53529
53530
53531
53532
53533
53534
53535
53536
53537
53538
53539
53540
53541
53542
53543
53544
53545
53546
53547
53548
53549
53550
53551
53552
53553
53554
53555
53556


53557

53558
53559
53560
53561
53562
53563
53564
53565
53566
53567
53568
53569
53570
53571
53572







53573
53574
53575
53576
53577
53578
53579
53580
    testcase( surplus==maxLocal );
    testcase( surplus==maxLocal+1 );
    if( surplus <= maxLocal ){
      pInfo->nLocal = (u16)surplus;
    }else{
      pInfo->nLocal = (u16)minLocal;
    }
    pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
    pInfo->nSize = pInfo->iOverflow + 4;
  }
}


static void btreeParseCell(
  MemPage *pPage,         /* Page containing the cell */
  int iCell,              /* The cell index.  First cell is 0 */
  CellInfo *pInfo         /* Fill in this structure */
){
  btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo);
}

/*
** Compute the total number of bytes that a Cell needs in the cell
** data area of the btree-page.  The return number includes the cell
** data header and the local payload, but not any overflow page or
** the space used by the cell pointer.
*/
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
  u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
  u8 *pEnd;                                /* End mark for a varint */
  u32 nSize;                               /* Size value to return */

#ifdef SQLITE_DEBUG
  /* The value returned by this function should always be the same as
  ** the (CellInfo.nSize) value found by doing a full parse of the
  ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
  ** this function verifies that this invariant is not violated. */
  CellInfo debuginfo;
  btreeParseCellPtr(pPage, pCell, &debuginfo);
#endif

  if( pPage->noPayload ){
    pEnd = &pIter[9];
    while( (*pIter++)&0x80 && pIter<pEnd );
    assert( pPage->childPtrSize==4 );
    return (u16)(pIter - pCell);
  }
  nSize = *pIter;
  if( nSize>=0x80 ){
    pEnd = &pIter[9];
    nSize &= 0x7f;
    do{
      nSize = (nSize<<7) | (*++pIter & 0x7f);
    }while( *(pIter)>=0x80 && pIter<pEnd );
  }
  pIter++;
  if( pPage->intKey ){
    /* pIter now points at the 64-bit integer key value, a variable length 
    ** integer. The following block moves pIter to point at the first byte
    ** past the end of the key value. */
    pEnd = &pIter[9];
    while( (*pIter++)&0x80 && pIter<pEnd );


  }

  testcase( nSize==pPage->maxLocal );
  testcase( nSize==pPage->maxLocal+1 );
  if( nSize<=pPage->maxLocal ){
    nSize += (u32)(pIter - pCell);
    if( nSize<4 ) nSize = 4;
  }else{
    int minLocal = pPage->minLocal;
    nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
    testcase( nSize==pPage->maxLocal );
    testcase( nSize==pPage->maxLocal+1 );
    if( nSize>pPage->maxLocal ){
      nSize = minLocal;
    }
    nSize += 4 + (u16)(pIter - pCell);
  }







  assert( nSize==debuginfo.nSize || CORRUPT_DB );
  return (u16)nSize;
}

#ifdef SQLITE_DEBUG
/* This variation on cellSizePtr() is used inside of assert() statements
** only. */
static u16 cellSize(MemPage *pPage, int iCell){
53192
53193
53194
53195
53196
53197
53198
53199
53200
53201
53202
53203
53204
53205
53206
53207
53208
53209
53210
53211
53212





53213
53214
53215
53216
53217
53218
53219
53220
53221
53222
53223
53224

53225
53226
53227
53228
53229
53230
53231
53232
53233
53234
53235
53236
53237
53238
53239
53240
53241
53242
53243
53244
53245
53246
53247
53248
53249
53250
53251
53252
53253
53254
53255
53256
53257
53258
53259
53260
53261
53262
53263
53264
53265
53266
53267
53268
53269
53270
53271
53272
53273
53274
53275
53276









53277
53278
53279
53280
53281
53282
53283
53284
53285
53286
53287
53288
53289































































53290
53291
53292
53293
53294
53295
53296
53297
53298
53299
53300
53301
53302
53303
53304
53305
53306
53307

53308
53309
53310
53311
53312
53313
53314
53315
53316
53317
53318
53319
53320
53321
53322
53323





53324
53325
53326
53327
53328
53329
53330
53331
53332
53333
53334
53335
53336
53337
53338
53339
53340
53341
53342
53343
53344
53345
53346
53347
53348
53349
53350
53351
53352
53353
53354
53355
53356
53357
53358
53359
53360
53361
53362
53363
53364
53365
53366
53367
53368
53369
53370
53371
53372
53373
53374
53375
53376
53377
53378
53379
53380
53381
53382
53383
** for the overflow page.
*/
static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
  CellInfo info;
  if( *pRC ) return;
  assert( pCell!=0 );
  btreeParseCellPtr(pPage, pCell, &info);
  assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
  if( info.iOverflow ){
    Pgno ovfl = get4byte(&pCell[info.iOverflow]);
    ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
  }
}
#endif


/*
** Defragment the page given.  All Cells are moved to the
** end of the page and all free space is collected into one
** big FreeBlk that occurs in between the header and cell
** pointer array and the cell content area.





*/
static int defragmentPage(MemPage *pPage){
  int i;                     /* Loop counter */
  int pc;                    /* Address of the i-th cell */
  int hdr;                   /* Offset to the page header */
  int size;                  /* Size of a cell */
  int usableSize;            /* Number of usable bytes on a page */
  int cellOffset;            /* Offset to the cell pointer array */
  int cbrk;                  /* Offset to the cell content area */
  int nCell;                 /* Number of cells on the page */
  unsigned char *data;       /* The page data */
  unsigned char *temp;       /* Temp area for cell content */

  int iCellFirst;            /* First allowable cell index */
  int iCellLast;             /* Last possible cell index */


  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt!=0 );
  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
  assert( pPage->nOverflow==0 );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  cellOffset = pPage->cellOffset;
  nCell = pPage->nCell;
  assert( nCell==get2byte(&data[hdr+3]) );
  usableSize = pPage->pBt->usableSize;
  cbrk = get2byte(&data[hdr+5]);
  memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk);
  cbrk = usableSize;
  iCellFirst = cellOffset + 2*nCell;
  iCellLast = usableSize - 4;
  for(i=0; i<nCell; i++){
    u8 *pAddr;     /* The i-th cell pointer */
    pAddr = &data[cellOffset + i*2];
    pc = get2byte(pAddr);
    testcase( pc==iCellFirst );
    testcase( pc==iCellLast );
#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    /* These conditions have already been verified in btreeInitPage()
    ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined 
    */
    if( pc<iCellFirst || pc>iCellLast ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( pc>=iCellFirst && pc<=iCellLast );
    size = cellSizePtr(pPage, &temp[pc]);
    cbrk -= size;
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    if( cbrk<iCellFirst ){
      return SQLITE_CORRUPT_BKPT;
    }
#else
    if( cbrk<iCellFirst || pc+size>usableSize ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
    testcase( cbrk+size==usableSize );
    testcase( pc+size==usableSize );
    memcpy(&data[cbrk], &temp[pc], size);
    put2byte(pAddr, cbrk);









  }
  assert( cbrk>=iCellFirst );
  put2byte(&data[hdr+5], cbrk);
  data[hdr+1] = 0;
  data[hdr+2] = 0;
  data[hdr+7] = 0;
  memset(&data[iCellFirst], 0, cbrk-iCellFirst);
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  if( cbrk-iCellFirst!=pPage->nFree ){
    return SQLITE_CORRUPT_BKPT;
  }
  return SQLITE_OK;
}
































































/*
** Allocate nByte bytes of space from within the B-Tree page passed
** as the first argument. Write into *pIdx the index into pPage->aData[]
** of the first byte of allocated space. Return either SQLITE_OK or
** an error code (usually SQLITE_CORRUPT).
**
** The caller guarantees that there is sufficient space to make the
** allocation.  This routine might need to defragment in order to bring
** all the space together, however.  This routine will avoid using
** the first two bytes past the cell pointer area since presumably this
** allocation is being made in order to insert a new cell, so we will
** also end up needing a new cell pointer.
*/
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  const int hdr = pPage->hdrOffset;    /* Local cache of pPage->hdrOffset */
  u8 * const data = pPage->aData;      /* Local cache of pPage->aData */
  int top;                             /* First byte of cell content area */

  int gap;        /* First byte of gap between cell pointers and cell content */
  int rc;         /* Integer return code */
  int usableSize; /* Usable size of the page */
  
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( nByte>=0 );  /* Minimum cell size is 4 */
  assert( pPage->nFree>=nByte );
  assert( pPage->nOverflow==0 );
  usableSize = pPage->pBt->usableSize;
  assert( nByte < usableSize-8 );

  assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
  gap = pPage->cellOffset + 2*pPage->nCell;
  assert( gap<=65536 );





  top = get2byte(&data[hdr+5]);
  if( gap>top ){
    if( top==0 ){
      top = 65536;
    }else{
      return SQLITE_CORRUPT_BKPT;
    }
  }

  /* If there is enough space between gap and top for one more cell pointer
  ** array entry offset, and if the freelist is not empty, then search the
  ** freelist looking for a free slot big enough to satisfy the request.
  */
  testcase( gap+2==top );
  testcase( gap+1==top );
  testcase( gap==top );
  if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
    int pc, addr;
    for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
      int size;            /* Size of the free slot */
      if( pc>usableSize-4 || pc<addr+4 ){
        return SQLITE_CORRUPT_BKPT;
      }
      size = get2byte(&data[pc+2]);
      if( size>=nByte ){
        int x = size - nByte;
        testcase( x==4 );
        testcase( x==3 );
        if( x<4 ){
          if( data[hdr+7]>=60 ) goto defragment_page;
          /* Remove the slot from the free-list. Update the number of
          ** fragmented bytes within the page. */
          memcpy(&data[addr], &data[pc], 2);
          data[hdr+7] += (u8)x;
        }else if( size+pc > usableSize ){
          return SQLITE_CORRUPT_BKPT;
        }else{
          /* The slot remains on the free-list. Reduce its size to account
          ** for the portion used by the new allocation. */
          put2byte(&data[pc+2], x);
        }
        *pIdx = pc + x;
        return SQLITE_OK;
      }
    }
  }

  /* The request could not be fulfilled using a freelist slot.  Check
  ** to see if defragmentation is necessary.
  */
  testcase( gap+2+nByte==top );
  if( gap+2+nByte>top ){
defragment_page:
    testcase( pPage->nCell==0 );
    rc = defragmentPage(pPage);
    if( rc ) return rc;
    top = get2byteNotZero(&data[hdr+5]);
    assert( gap+nByte<=top );
  }








<













>
>
>
>
>












>









|
|





<
<


















|













<

>
>
>
>
>
>
>
>
>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


















>

<
<







<
|




>
>
>
>
>
|
<
<
<
<
|
<
<









|
<
<
<
<
<
<
|
<
<
<
|
|
<
<
<
<
|
<
<
<
<
|
<
|
|
<








|







53589
53590
53591
53592
53593
53594
53595

53596
53597
53598
53599
53600
53601
53602
53603
53604
53605
53606
53607
53608
53609
53610
53611
53612
53613
53614
53615
53616
53617
53618
53619
53620
53621
53622
53623
53624
53625
53626
53627
53628
53629
53630
53631
53632
53633
53634
53635
53636
53637
53638
53639
53640
53641
53642


53643
53644
53645
53646
53647
53648
53649
53650
53651
53652
53653
53654
53655
53656
53657
53658
53659
53660
53661
53662
53663
53664
53665
53666
53667
53668
53669
53670
53671
53672
53673
53674

53675
53676
53677
53678
53679
53680
53681
53682
53683
53684
53685
53686
53687
53688
53689
53690
53691
53692
53693
53694
53695
53696
53697
53698
53699
53700
53701
53702
53703
53704
53705
53706
53707
53708
53709
53710
53711
53712
53713
53714
53715
53716
53717
53718
53719
53720
53721
53722
53723
53724
53725
53726
53727
53728
53729
53730
53731
53732
53733
53734
53735
53736
53737
53738
53739
53740
53741
53742
53743
53744
53745
53746
53747
53748
53749
53750
53751
53752
53753
53754
53755
53756
53757
53758
53759
53760
53761
53762
53763
53764
53765
53766
53767
53768
53769
53770
53771
53772
53773
53774
53775
53776
53777
53778
53779
53780


53781
53782
53783
53784
53785
53786
53787

53788
53789
53790
53791
53792
53793
53794
53795
53796
53797
53798




53799


53800
53801
53802
53803
53804
53805
53806
53807
53808
53809






53810



53811
53812




53813




53814

53815
53816

53817
53818
53819
53820
53821
53822
53823
53824
53825
53826
53827
53828
53829
53830
53831
53832
** for the overflow page.
*/
static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
  CellInfo info;
  if( *pRC ) return;
  assert( pCell!=0 );
  btreeParseCellPtr(pPage, pCell, &info);

  if( info.iOverflow ){
    Pgno ovfl = get4byte(&pCell[info.iOverflow]);
    ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
  }
}
#endif


/*
** Defragment the page given.  All Cells are moved to the
** end of the page and all free space is collected into one
** big FreeBlk that occurs in between the header and cell
** pointer array and the cell content area.
**
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
** b-tree page so that there are no freeblocks or fragment bytes, all
** unused bytes are contained in the unallocated space region, and all
** cells are packed tightly at the end of the page.
*/
static int defragmentPage(MemPage *pPage){
  int i;                     /* Loop counter */
  int pc;                    /* Address of the i-th cell */
  int hdr;                   /* Offset to the page header */
  int size;                  /* Size of a cell */
  int usableSize;            /* Number of usable bytes on a page */
  int cellOffset;            /* Offset to the cell pointer array */
  int cbrk;                  /* Offset to the cell content area */
  int nCell;                 /* Number of cells on the page */
  unsigned char *data;       /* The page data */
  unsigned char *temp;       /* Temp area for cell content */
  unsigned char *src;        /* Source of content */
  int iCellFirst;            /* First allowable cell index */
  int iCellLast;             /* Last possible cell index */


  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt!=0 );
  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
  assert( pPage->nOverflow==0 );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  temp = 0;
  src = data = pPage->aData;
  hdr = pPage->hdrOffset;
  cellOffset = pPage->cellOffset;
  nCell = pPage->nCell;
  assert( nCell==get2byte(&data[hdr+3]) );
  usableSize = pPage->pBt->usableSize;


  cbrk = usableSize;
  iCellFirst = cellOffset + 2*nCell;
  iCellLast = usableSize - 4;
  for(i=0; i<nCell; i++){
    u8 *pAddr;     /* The i-th cell pointer */
    pAddr = &data[cellOffset + i*2];
    pc = get2byte(pAddr);
    testcase( pc==iCellFirst );
    testcase( pc==iCellLast );
#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    /* These conditions have already been verified in btreeInitPage()
    ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined 
    */
    if( pc<iCellFirst || pc>iCellLast ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( pc>=iCellFirst && pc<=iCellLast );
    size = cellSizePtr(pPage, &src[pc]);
    cbrk -= size;
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    if( cbrk<iCellFirst ){
      return SQLITE_CORRUPT_BKPT;
    }
#else
    if( cbrk<iCellFirst || pc+size>usableSize ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
    testcase( cbrk+size==usableSize );
    testcase( pc+size==usableSize );

    put2byte(pAddr, cbrk);
    if( temp==0 ){
      int x;
      if( cbrk==pc ) continue;
      temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
      x = get2byte(&data[hdr+5]);
      memcpy(&temp[x], &data[x], (cbrk+size) - x);
      src = temp;
    }
    memcpy(&data[cbrk], &src[pc], size);
  }
  assert( cbrk>=iCellFirst );
  put2byte(&data[hdr+5], cbrk);
  data[hdr+1] = 0;
  data[hdr+2] = 0;
  data[hdr+7] = 0;
  memset(&data[iCellFirst], 0, cbrk-iCellFirst);
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  if( cbrk-iCellFirst!=pPage->nFree ){
    return SQLITE_CORRUPT_BKPT;
  }
  return SQLITE_OK;
}

/*
** Search the free-list on page pPg for space to store a cell nByte bytes in
** size. If one can be found, return a pointer to the space and remove it
** from the free-list.
**
** If no suitable space can be found on the free-list, return NULL.
**
** This function may detect corruption within pPg.  If corruption is
** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned.
**
** If a slot of at least nByte bytes is found but cannot be used because 
** there are already at least 60 fragmented bytes on the page, return NULL.
** In this case, if pbDefrag parameter is not NULL, set *pbDefrag to true.
*/
static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){
  const int hdr = pPg->hdrOffset;
  u8 * const aData = pPg->aData;
  int iAddr;
  int pc;
  int usableSize = pPg->pBt->usableSize;

  for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){
    int size;            /* Size of the free slot */
    /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
    ** increasing offset. */
    if( pc>usableSize-4 || pc<iAddr+4 ){
      *pRc = SQLITE_CORRUPT_BKPT;
      return 0;
    }
    /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
    ** freeblock form a big-endian integer which is the size of the freeblock
    ** in bytes, including the 4-byte header. */
    size = get2byte(&aData[pc+2]);
    if( size>=nByte ){
      int x = size - nByte;
      testcase( x==4 );
      testcase( x==3 );
      if( x<4 ){
        /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
        ** number of bytes in fragments may not exceed 60. */
        if( aData[hdr+7]>=60 ){
          if( pbDefrag ) *pbDefrag = 1;
          return 0;
        }
        /* Remove the slot from the free-list. Update the number of
        ** fragmented bytes within the page. */
        memcpy(&aData[iAddr], &aData[pc], 2);
        aData[hdr+7] += (u8)x;
      }else if( size+pc > usableSize ){
        *pRc = SQLITE_CORRUPT_BKPT;
        return 0;
      }else{
        /* The slot remains on the free-list. Reduce its size to account
         ** for the portion used by the new allocation. */
        put2byte(&aData[pc+2], x);
      }
      return &aData[pc + x];
    }
  }

  return 0;
}

/*
** Allocate nByte bytes of space from within the B-Tree page passed
** as the first argument. Write into *pIdx the index into pPage->aData[]
** of the first byte of allocated space. Return either SQLITE_OK or
** an error code (usually SQLITE_CORRUPT).
**
** The caller guarantees that there is sufficient space to make the
** allocation.  This routine might need to defragment in order to bring
** all the space together, however.  This routine will avoid using
** the first two bytes past the cell pointer area since presumably this
** allocation is being made in order to insert a new cell, so we will
** also end up needing a new cell pointer.
*/
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  const int hdr = pPage->hdrOffset;    /* Local cache of pPage->hdrOffset */
  u8 * const data = pPage->aData;      /* Local cache of pPage->aData */
  int top;                             /* First byte of cell content area */
  int rc = SQLITE_OK;                  /* Integer return code */
  int gap;        /* First byte of gap between cell pointers and cell content */


  
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( nByte>=0 );  /* Minimum cell size is 4 */
  assert( pPage->nFree>=nByte );
  assert( pPage->nOverflow==0 );

  assert( nByte < (int)(pPage->pBt->usableSize-8) );

  assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
  gap = pPage->cellOffset + 2*pPage->nCell;
  assert( gap<=65536 );
  /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
  ** and the reserved space is zero (the usual value for reserved space)
  ** then the cell content offset of an empty page wants to be 65536.
  ** However, that integer is too large to be stored in a 2-byte unsigned
  ** integer, so a value of 0 is used in its place. */
  top = get2byteNotZero(&data[hdr+5]);




  if( gap>top ) return SQLITE_CORRUPT_BKPT;



  /* If there is enough space between gap and top for one more cell pointer
  ** array entry offset, and if the freelist is not empty, then search the
  ** freelist looking for a free slot big enough to satisfy the request.
  */
  testcase( gap+2==top );
  testcase( gap+1==top );
  testcase( gap==top );
  if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
    int bDefrag = 0;






    u8 *pSpace = pageFindSlot(pPage, nByte, &rc, &bDefrag);



    if( rc ) return rc;
    if( bDefrag ) goto defragment_page;




    if( pSpace ){




      assert( pSpace>=data && (pSpace - data)<65536 );

      *pIdx = (int)(pSpace - data);
      return SQLITE_OK;

    }
  }

  /* The request could not be fulfilled using a freelist slot.  Check
  ** to see if defragmentation is necessary.
  */
  testcase( gap+2+nByte==top );
  if( gap+2+nByte>top ){
 defragment_page:
    testcase( pPage->nCell==0 );
    rc = defragmentPage(pPage);
    if( rc ) return rc;
    top = get2byteNotZero(&data[hdr+5]);
    assert( gap+nByte<=top );
  }

53405
53406
53407
53408
53409
53410
53411
53412
53413
53414
53415
53416
53417
53418
53419
53420
53421
53422
53423
53424
53425
53426
53427
53428
53429
53430
53431
** Note that even though the freeblock list was checked by btreeInitPage(),
** that routine will not detect overlap between cells or freeblocks.  Nor
** does it detect cells or freeblocks that encrouch into the reserved bytes
** at the end of the page.  So do additional corruption checks inside this
** routine and return SQLITE_CORRUPT if any problems are found.
*/
static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
  u16 iPtr;                             /* Address of pointer to next freeblock */
  u16 iFreeBlk;                         /* Address of the next freeblock */
  u8 hdr;                               /* Page header size.  0 or 100 */
  u8 nFrag = 0;                         /* Reduction in fragmentation */
  u16 iOrigSize = iSize;                /* Original value of iSize */
  u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
  u32 iEnd = iStart + iSize;            /* First byte past the iStart buffer */
  unsigned char *data = pPage->aData;   /* Page content */

  assert( pPage->pBt!=0 );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
  assert( iEnd <= pPage->pBt->usableSize );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( iSize>=4 );   /* Minimum cell size is 4 */
  assert( iStart<=iLast );

  /* Overwrite deleted information with zeros when the secure_delete
  ** option is enabled */
  if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){







|











|







53854
53855
53856
53857
53858
53859
53860
53861
53862
53863
53864
53865
53866
53867
53868
53869
53870
53871
53872
53873
53874
53875
53876
53877
53878
53879
53880
** Note that even though the freeblock list was checked by btreeInitPage(),
** that routine will not detect overlap between cells or freeblocks.  Nor
** does it detect cells or freeblocks that encrouch into the reserved bytes
** at the end of the page.  So do additional corruption checks inside this
** routine and return SQLITE_CORRUPT if any problems are found.
*/
static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
  u16 iPtr;                             /* Address of ptr to next freeblock */
  u16 iFreeBlk;                         /* Address of the next freeblock */
  u8 hdr;                               /* Page header size.  0 or 100 */
  u8 nFrag = 0;                         /* Reduction in fragmentation */
  u16 iOrigSize = iSize;                /* Original value of iSize */
  u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
  u32 iEnd = iStart + iSize;            /* First byte past the iStart buffer */
  unsigned char *data = pPage->aData;   /* Page content */

  assert( pPage->pBt!=0 );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
  assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( iSize>=4 );   /* Minimum cell size is 4 */
  assert( iStart<=iLast );

  /* Overwrite deleted information with zeros when the secure_delete
  ** option is enabled */
  if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
53457
53458
53459
53460
53461
53462
53463
53464
53465
53466
53467
53468
53469
53470
53471
53472
53473
      nFrag = iFreeBlk - iEnd;
      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
      iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
      iSize = iEnd - iStart;
      iFreeBlk = get2byte(&data[iFreeBlk]);
    }
  
    /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
    ** in the page header) then check to see if iStart should be coalesced 
    ** onto the end of iPtr.
    */
    if( iPtr>hdr+1 ){
      int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
      if( iPtrEnd+3>=iStart ){
        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
        nFrag += iStart - iPtrEnd;
        iSize = iEnd - iPtr;







|
|
|







53906
53907
53908
53909
53910
53911
53912
53913
53914
53915
53916
53917
53918
53919
53920
53921
53922
      nFrag = iFreeBlk - iEnd;
      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
      iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
      iSize = iEnd - iStart;
      iFreeBlk = get2byte(&data[iFreeBlk]);
    }
  
    /* If iPtr is another freeblock (that is, if iPtr is not the freelist
    ** pointer in the page header) then check to see if iStart should be
    ** coalesced onto the end of iPtr.
    */
    if( iPtr>hdr+1 ){
      int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
      if( iPtrEnd+3>=iStart ){
        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
        nFrag += iStart - iPtrEnd;
        iSize = iEnd - iPtr;
53512
53513
53514
53515
53516
53517
53518






53519
53520

53521
53522
53523






53524
53525

53526
53527
53528


53529
53530
53531
53532
53533
53534
53535
  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  pPage->leaf = (u8)(flagByte>>3);  assert( PTF_LEAF == 1<<3 );
  flagByte &= ~PTF_LEAF;
  pPage->childPtrSize = 4-4*pPage->leaf;
  pBt = pPage->pBt;
  if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){






    pPage->intKey = 1;
    pPage->hasData = pPage->leaf;

    pPage->maxLocal = pBt->maxLeaf;
    pPage->minLocal = pBt->minLeaf;
  }else if( flagByte==PTF_ZERODATA ){






    pPage->intKey = 0;
    pPage->hasData = 0;

    pPage->maxLocal = pBt->maxLocal;
    pPage->minLocal = pBt->minLocal;
  }else{


    return SQLITE_CORRUPT_BKPT;
  }
  pPage->max1bytePayload = pBt->max1bytePayload;
  return SQLITE_OK;
}

/*







>
>
>
>
>
>

|
>



>
>
>
>
>
>

|
>



>
>







53961
53962
53963
53964
53965
53966
53967
53968
53969
53970
53971
53972
53973
53974
53975
53976
53977
53978
53979
53980
53981
53982
53983
53984
53985
53986
53987
53988
53989
53990
53991
53992
53993
53994
53995
53996
53997
53998
53999
54000
  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  pPage->leaf = (u8)(flagByte>>3);  assert( PTF_LEAF == 1<<3 );
  flagByte &= ~PTF_LEAF;
  pPage->childPtrSize = 4-4*pPage->leaf;
  pBt = pPage->pBt;
  if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
    /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior
    ** table b-tree page. */
    assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
    /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf
    ** table b-tree page. */
    assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
    pPage->intKey = 1;
    pPage->intKeyLeaf = pPage->leaf;
    pPage->noPayload = !pPage->leaf;
    pPage->maxLocal = pBt->maxLeaf;
    pPage->minLocal = pBt->minLeaf;
  }else if( flagByte==PTF_ZERODATA ){
    /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior
    ** index b-tree page. */
    assert( (PTF_ZERODATA)==2 );
    /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf
    ** index b-tree page. */
    assert( (PTF_ZERODATA|PTF_LEAF)==10 );
    pPage->intKey = 0;
    pPage->intKeyLeaf = 0;
    pPage->noPayload = 0;
    pPage->maxLocal = pBt->maxLocal;
    pPage->minLocal = pBt->minLocal;
  }else{
    /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
    ** an error. */
    return SQLITE_CORRUPT_BKPT;
  }
  pPage->max1bytePayload = pBt->max1bytePayload;
  return SQLITE_OK;
}

/*
53561
53562
53563
53564
53565
53566
53567


53568
53569
53570
53571
53572
53573
53574
53575



53576


53577
53578
53579
53580
53581
53582





53583
53584
53585
53586
53587
53588
53589
    int iCellFirst;    /* First allowable cell or freeblock offset */
    int iCellLast;     /* Last possible cell or freeblock offset */

    pBt = pPage->pBt;

    hdr = pPage->hdrOffset;
    data = pPage->aData;


    if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
    assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
    pPage->maskPage = (u16)(pBt->pageSize - 1);
    pPage->nOverflow = 0;
    usableSize = pBt->usableSize;
    pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
    pPage->aDataEnd = &data[usableSize];
    pPage->aCellIdx = &data[cellOffset];



    top = get2byteNotZero(&data[hdr+5]);


    pPage->nCell = get2byte(&data[hdr+3]);
    if( pPage->nCell>MX_CELL(pBt) ){
      /* To many cells for a single page.  The page must be corrupt */
      return SQLITE_CORRUPT_BKPT;
    }
    testcase( pPage->nCell==MX_CELL(pBt) );






    /* A malformed database page might cause us to read past the end
    ** of page when parsing a cell.  
    **
    ** The following block of code checks early to see if a cell extends
    ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
    ** returned if it does.







>
>





|


>
>
>

>
>






>
>
>
>
>







54026
54027
54028
54029
54030
54031
54032
54033
54034
54035
54036
54037
54038
54039
54040
54041
54042
54043
54044
54045
54046
54047
54048
54049
54050
54051
54052
54053
54054
54055
54056
54057
54058
54059
54060
54061
54062
54063
54064
54065
54066
    int iCellFirst;    /* First allowable cell or freeblock offset */
    int iCellLast;     /* Last possible cell or freeblock offset */

    pBt = pPage->pBt;

    hdr = pPage->hdrOffset;
    data = pPage->aData;
    /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
    ** the b-tree page type. */
    if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
    assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
    pPage->maskPage = (u16)(pBt->pageSize - 1);
    pPage->nOverflow = 0;
    usableSize = pBt->usableSize;
    pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
    pPage->aDataEnd = &data[usableSize];
    pPage->aCellIdx = &data[cellOffset];
    /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
    ** the start of the cell content area. A zero value for this integer is
    ** interpreted as 65536. */
    top = get2byteNotZero(&data[hdr+5]);
    /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
    ** number of cells on the page. */
    pPage->nCell = get2byte(&data[hdr+3]);
    if( pPage->nCell>MX_CELL(pBt) ){
      /* To many cells for a single page.  The page must be corrupt */
      return SQLITE_CORRUPT_BKPT;
    }
    testcase( pPage->nCell==MX_CELL(pBt) );
    /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
    ** possible for a root page of a table that contains no rows) then the
    ** offset to the cell content area will equal the page size minus the
    ** bytes of reserved space. */
    assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );

    /* A malformed database page might cause us to read past the end
    ** of page when parsing a cell.  
    **
    ** The following block of code checks early to see if a cell extends
    ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
    ** returned if it does.
53609
53610
53611
53612
53613
53614
53615
53616



53617
53618
53619
53620
53621



53622

53623
53624
53625
53626
53627
53628
53629
          return SQLITE_CORRUPT_BKPT;
        }
      }
      if( !pPage->leaf ) iCellLast++;
    }  
#endif

    /* Compute the total free space on the page */



    pc = get2byte(&data[hdr+1]);
    nFree = data[hdr+7] + top;
    while( pc>0 ){
      u16 next, size;
      if( pc<iCellFirst || pc>iCellLast ){



        /* Start of free block is off the page */

        return SQLITE_CORRUPT_BKPT; 
      }
      next = get2byte(&data[pc]);
      size = get2byte(&data[pc+2]);
      if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
        /* Free blocks must be in ascending order. And the last byte of
        ** the free-block must lie on the database page.  */







|
>
>
>

|



>
>
>
|
>







54086
54087
54088
54089
54090
54091
54092
54093
54094
54095
54096
54097
54098
54099
54100
54101
54102
54103
54104
54105
54106
54107
54108
54109
54110
54111
54112
54113
          return SQLITE_CORRUPT_BKPT;
        }
      }
      if( !pPage->leaf ) iCellLast++;
    }  
#endif

    /* Compute the total free space on the page
    ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
    ** start of the first freeblock on the page, or is zero if there are no
    ** freeblocks. */
    pc = get2byte(&data[hdr+1]);
    nFree = data[hdr+7] + top;  /* Init nFree to non-freeblock free space */
    while( pc>0 ){
      u16 next, size;
      if( pc<iCellFirst || pc>iCellLast ){
        /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
        ** always be at least one cell before the first freeblock.
        **
        ** Or, the freeblock is off the end of the page
        */
        return SQLITE_CORRUPT_BKPT; 
      }
      next = get2byte(&data[pc]);
      size = get2byte(&data[pc+2]);
      if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
        /* Free blocks must be in ascending order. And the last byte of
        ** the free-block must lie on the database page.  */
54021
54022
54023
54024
54025
54026
54027



54028
54029
54030
54031
54032
54033
54034
54035
54036
54037
54038
54039
54040
54041
54042
54043
54044
54045



54046
54047
54048
54049
54050
54051
54052
  
    pBt->pCursor = 0;
    pBt->pPage1 = 0;
    if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY;
#ifdef SQLITE_SECURE_DELETE
    pBt->btsFlags |= BTS_SECURE_DELETE;
#endif



    pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
    if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
         || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
      pBt->pageSize = 0;
#ifndef SQLITE_OMIT_AUTOVACUUM
      /* If the magic name ":memory:" will create an in-memory database, then
      ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
      ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
      ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
      ** regular file-name. In this case the auto-vacuum applies as per normal.
      */
      if( zFilename && !isMemdb ){
        pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0);
        pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0);
      }
#endif
      nReserve = 0;
    }else{



      nReserve = zDbHeader[20];
      pBt->btsFlags |= BTS_PAGESIZE_FIXED;
#ifndef SQLITE_OMIT_AUTOVACUUM
      pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
      pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0);
#endif
    }







>
>
>


















>
>
>







54505
54506
54507
54508
54509
54510
54511
54512
54513
54514
54515
54516
54517
54518
54519
54520
54521
54522
54523
54524
54525
54526
54527
54528
54529
54530
54531
54532
54533
54534
54535
54536
54537
54538
54539
54540
54541
54542
  
    pBt->pCursor = 0;
    pBt->pPage1 = 0;
    if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY;
#ifdef SQLITE_SECURE_DELETE
    pBt->btsFlags |= BTS_SECURE_DELETE;
#endif
    /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
    ** determined by the 2-byte integer located at an offset of 16 bytes from
    ** the beginning of the database file. */
    pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
    if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
         || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
      pBt->pageSize = 0;
#ifndef SQLITE_OMIT_AUTOVACUUM
      /* If the magic name ":memory:" will create an in-memory database, then
      ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
      ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
      ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
      ** regular file-name. In this case the auto-vacuum applies as per normal.
      */
      if( zFilename && !isMemdb ){
        pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0);
        pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0);
      }
#endif
      nReserve = 0;
    }else{
      /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is
      ** determined by the one-byte unsigned integer found at an offset of 20
      ** into the database file header. */
      nReserve = zDbHeader[20];
      pBt->btsFlags |= BTS_PAGESIZE_FIXED;
#ifndef SQLITE_OMIT_AUTOVACUUM
      pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
      pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0);
#endif
    }
54173
54174
54175
54176
54177
54178
54179
54180

54181
54182
54183
54184
54185
54186
54187
54188
54189
54190
54191
54192
54193
54194
54195





54196



54197
54198
54199
54200
54201
54202
54203
54204


54205

54206
54207
54208
54209
54210
54211
54212
#else
  return 1;
#endif
}

/*
** Make sure pBt->pTmpSpace points to an allocation of 
** MX_CELL_SIZE(pBt) bytes.

*/
static void allocateTempSpace(BtShared *pBt){
  if( !pBt->pTmpSpace ){
    pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );

    /* One of the uses of pBt->pTmpSpace is to format cells before
    ** inserting them into a leaf page (function fillInCell()). If
    ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
    ** by the various routines that manipulate binary cells. Which
    ** can mean that fillInCell() only initializes the first 2 or 3
    ** bytes of pTmpSpace, but that the first 4 bytes are copied from
    ** it into a database page. This is not actually a problem, but it
    ** does cause a valgrind error when the 1 or 2 bytes of unitialized 
    ** data is passed to system call write(). So to avoid this error,
    ** zero the first 4 bytes of temp space here.  */





    if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4);



  }
}

/*
** Free the pBt->pTmpSpace allocation
*/
static void freeTempSpace(BtShared *pBt){
  sqlite3PageFree( pBt->pTmpSpace);


  pBt->pTmpSpace = 0;

}

/*
** Close an open database and invalidate all cursors.
*/
SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
  BtShared *pBt = p->pBt;







|
>














|
>
>
>
>
>
|
>
>
>







|
>
>
|
>







54663
54664
54665
54666
54667
54668
54669
54670
54671
54672
54673
54674
54675
54676
54677
54678
54679
54680
54681
54682
54683
54684
54685
54686
54687
54688
54689
54690
54691
54692
54693
54694
54695
54696
54697
54698
54699
54700
54701
54702
54703
54704
54705
54706
54707
54708
54709
54710
54711
54712
54713
54714
#else
  return 1;
#endif
}

/*
** Make sure pBt->pTmpSpace points to an allocation of 
** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
** pointer.
*/
static void allocateTempSpace(BtShared *pBt){
  if( !pBt->pTmpSpace ){
    pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );

    /* One of the uses of pBt->pTmpSpace is to format cells before
    ** inserting them into a leaf page (function fillInCell()). If
    ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
    ** by the various routines that manipulate binary cells. Which
    ** can mean that fillInCell() only initializes the first 2 or 3
    ** bytes of pTmpSpace, but that the first 4 bytes are copied from
    ** it into a database page. This is not actually a problem, but it
    ** does cause a valgrind error when the 1 or 2 bytes of unitialized 
    ** data is passed to system call write(). So to avoid this error,
    ** zero the first 4 bytes of temp space here.
    **
    ** Also:  Provide four bytes of initialized space before the
    ** beginning of pTmpSpace as an area available to prepend the
    ** left-child pointer to the beginning of a cell.
    */
    if( pBt->pTmpSpace ){
      memset(pBt->pTmpSpace, 0, 8);
      pBt->pTmpSpace += 4;
    }
  }
}

/*
** Free the pBt->pTmpSpace allocation
*/
static void freeTempSpace(BtShared *pBt){
  if( pBt->pTmpSpace ){
    pBt->pTmpSpace -= 4;
    sqlite3PageFree(pBt->pTmpSpace);
    pBt->pTmpSpace = 0;
  }
}

/*
** Close an open database and invalidate all cursors.
*/
SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
  BtShared *pBt = p->pBt;
54224
54225
54226
54227
54228
54229
54230
54231
54232
54233
54234
54235
54236
54237
54238
    }
  }

  /* Rollback any active transaction and free the handle structure.
  ** The call to sqlite3BtreeRollback() drops any table-locks held by
  ** this handle.
  */
  sqlite3BtreeRollback(p, SQLITE_OK);
  sqlite3BtreeLeave(p);

  /* If there are still other outstanding references to the shared-btree
  ** structure, return now. The remainder of this procedure cleans 
  ** up the shared-btree.
  */
  assert( p->wantToLock==0 && p->locked==0 );







|







54726
54727
54728
54729
54730
54731
54732
54733
54734
54735
54736
54737
54738
54739
54740
    }
  }

  /* Rollback any active transaction and free the handle structure.
  ** The call to sqlite3BtreeRollback() drops any table-locks held by
  ** this handle.
  */
  sqlite3BtreeRollback(p, SQLITE_OK, 0);
  sqlite3BtreeLeave(p);

  /* If there are still other outstanding references to the shared-btree
  ** structure, return now. The remainder of this procedure cleans 
  ** up the shared-btree.
  */
  assert( p->wantToLock==0 && p->locked==0 );
54536
54537
54538
54539
54540
54541
54542



54543
54544
54545
54546
54547
54548
54549
    nPage = nPageFile;
  }
  if( nPage>0 ){
    u32 pageSize;
    u32 usableSize;
    u8 *page1 = pPage1->aData;
    rc = SQLITE_NOTADB;



    if( memcmp(page1, zMagicHeader, 16)!=0 ){
      goto page1_init_failed;
    }

#ifdef SQLITE_OMIT_WAL
    if( page1[18]>1 ){
      pBt->btsFlags |= BTS_READ_ONLY;







>
>
>







55038
55039
55040
55041
55042
55043
55044
55045
55046
55047
55048
55049
55050
55051
55052
55053
55054
    nPage = nPageFile;
  }
  if( nPage>0 ){
    u32 pageSize;
    u32 usableSize;
    u8 *page1 = pPage1->aData;
    rc = SQLITE_NOTADB;
    /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
    ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d
    ** 61 74 20 33 00. */
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
      goto page1_init_failed;
    }

#ifdef SQLITE_OMIT_WAL
    if( page1[18]>1 ){
      pBt->btsFlags |= BTS_READ_ONLY;
54576
54577
54578
54579
54580
54581
54582
54583
54584

54585
54586
54587
54588
54589
54590



54591


54592
54593
54594
54595
54596
54597
54598







54599
54600
54601
54602
54603
54604
54605
54606
54607
54608
54609
54610
54611
54612
54613
54614
54615
54616
54617
54618



54619
54620
54621
54622
54623
54624
54625
        releasePage(pPage1);
        return SQLITE_OK;
      }
      rc = SQLITE_NOTADB;
    }
#endif

    /* The maximum embedded fraction must be exactly 25%.  And the minimum
    ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.

    ** The original design allowed these amounts to vary, but as of
    ** version 3.6.0, we require them to be fixed.
    */
    if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
      goto page1_init_failed;
    }



    pageSize = (page1[16]<<8) | (page1[17]<<16);


    if( ((pageSize-1)&pageSize)!=0
     || pageSize>SQLITE_MAX_PAGE_SIZE 
     || pageSize<=256 
    ){
      goto page1_init_failed;
    }
    assert( (pageSize & 7)==0 );







    usableSize = pageSize - page1[20];
    if( (u32)pageSize!=pBt->pageSize ){
      /* After reading the first page of the database assuming a page size
      ** of BtShared.pageSize, we have discovered that the page-size is
      ** actually pageSize. Unlock the database, leave pBt->pPage1 at
      ** zero and return SQLITE_OK. The caller will call this function
      ** again with the correct page-size.
      */
      releasePage(pPage1);
      pBt->usableSize = usableSize;
      pBt->pageSize = pageSize;
      freeTempSpace(pBt);
      rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
                                   pageSize-usableSize);
      return rc;
    }
    if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){
      rc = SQLITE_CORRUPT_BKPT;
      goto page1_init_failed;
    }



    if( usableSize<480 ){
      goto page1_init_failed;
    }
    pBt->pageSize = pageSize;
    pBt->usableSize = usableSize;
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);







|
|
>






>
>
>

>
>







>
>
>
>
>
>
>




















>
>
>







55081
55082
55083
55084
55085
55086
55087
55088
55089
55090
55091
55092
55093
55094
55095
55096
55097
55098
55099
55100
55101
55102
55103
55104
55105
55106
55107
55108
55109
55110
55111
55112
55113
55114
55115
55116
55117
55118
55119
55120
55121
55122
55123
55124
55125
55126
55127
55128
55129
55130
55131
55132
55133
55134
55135
55136
55137
55138
55139
55140
55141
55142
55143
55144
55145
55146
        releasePage(pPage1);
        return SQLITE_OK;
      }
      rc = SQLITE_NOTADB;
    }
#endif

    /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload
    ** fractions and the leaf payload fraction values must be 64, 32, and 32.
    **
    ** The original design allowed these amounts to vary, but as of
    ** version 3.6.0, we require them to be fixed.
    */
    if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
      goto page1_init_failed;
    }
    /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
    ** determined by the 2-byte integer located at an offset of 16 bytes from
    ** the beginning of the database file. */
    pageSize = (page1[16]<<8) | (page1[17]<<16);
    /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two
    ** between 512 and 65536 inclusive. */
    if( ((pageSize-1)&pageSize)!=0
     || pageSize>SQLITE_MAX_PAGE_SIZE 
     || pageSize<=256 
    ){
      goto page1_init_failed;
    }
    assert( (pageSize & 7)==0 );
    /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
    ** integer at offset 20 is the number of bytes of space at the end of
    ** each page to reserve for extensions. 
    **
    ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is
    ** determined by the one-byte unsigned integer found at an offset of 20
    ** into the database file header. */
    usableSize = pageSize - page1[20];
    if( (u32)pageSize!=pBt->pageSize ){
      /* After reading the first page of the database assuming a page size
      ** of BtShared.pageSize, we have discovered that the page-size is
      ** actually pageSize. Unlock the database, leave pBt->pPage1 at
      ** zero and return SQLITE_OK. The caller will call this function
      ** again with the correct page-size.
      */
      releasePage(pPage1);
      pBt->usableSize = usableSize;
      pBt->pageSize = pageSize;
      freeTempSpace(pBt);
      rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
                                   pageSize-usableSize);
      return rc;
    }
    if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){
      rc = SQLITE_CORRUPT_BKPT;
      goto page1_init_failed;
    }
    /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
    ** be less than 480. In other words, if the page size is 512, then the
    ** reserved space size cannot exceed 32. */
    if( usableSize<480 ){
      goto page1_init_failed;
    }
    pBt->pageSize = pageSize;
    pBt->usableSize = usableSize;
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
54692
54693
54694
54695
54696
54697
54698

54699
54700
54701
54702
54703
54704
54705
54706
54707
54708
54709
54710
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(BtShared *pBt){
  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE );
  if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){

    assert( pBt->pPage1->aData );
    assert( sqlite3PagerRefcount(pBt->pPager)==1 );
    assert( pBt->pPage1->aData );
    releasePage(pBt->pPage1);
    pBt->pPage1 = 0;
  }
}

/*
** If pBt points to an empty file then convert that empty file
** into a new empty database by initializing the first page of
** the database.







>
|

|
|
<







55213
55214
55215
55216
55217
55218
55219
55220
55221
55222
55223
55224

55225
55226
55227
55228
55229
55230
55231
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(BtShared *pBt){
  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE );
  if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
    MemPage *pPage1 = pBt->pPage1;
    assert( pPage1->aData );
    assert( sqlite3PagerRefcount(pBt->pPager)==1 );
    pBt->pPage1 = 0;
    releasePage(pPage1);

  }
}

/*
** If pBt points to an empty file then convert that empty file
** into a new empty database by initializing the first page of
** the database.
55517
55518
55519
55520
55521
55522
55523
55524
55525

55526
55527
55528
55529
55530
55531
55532
55533

55534


55535
55536
55537






55538
55539
55540



55541
55542
55543
55544









55545
55546
55547

55548
55549
55550
55551
55552
55553
55554

55555

55556
55557



55558
55559
55560
55561
55562
55563
55564
55565
55566
55567
55568
55569


55570
55571
55572

55573
55574
55575
55576
55577


55578
55579
55580
55581
55582
55583
55584
  }
  sqlite3BtreeLeave(p);
  return rc;
}

/*
** This routine sets the state to CURSOR_FAULT and the error
** code to errCode for every cursor on BtShared that pBtree
** references.

**
** Every cursor is tripped, including cursors that belong
** to other database connections that happen to be sharing
** the cache with pBtree.
**
** This routine gets called when a rollback occurs.
** All cursors using the same cache must be tripped
** to prevent them from trying to use the btree after

** the rollback.  The rollback may have deleted tables


** or moved root pages, so it is not sufficient to
** save the state of the cursor.  The cursor must be
** invalidated.






*/
SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
  BtCursor *p;



  if( pBtree==0 ) return;
  sqlite3BtreeEnter(pBtree);
  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
    int i;









    sqlite3BtreeClearCursor(p);
    p->eState = CURSOR_FAULT;
    p->skipNext = errCode;

    for(i=0; i<=p->iPage; i++){
      releasePage(p->apPage[i]);
      p->apPage[i] = 0;
    }
  }
  sqlite3BtreeLeave(pBtree);
}



/*
** Rollback the transaction in progress.  All cursors will be



** invalided by this operation.  Any attempt to use a cursor
** that was open at the beginning of this operation will result
** in an error.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
  int rc;
  BtShared *pBt = p->pBt;
  MemPage *pPage1;



  sqlite3BtreeEnter(p);
  if( tripCode==SQLITE_OK ){
    rc = tripCode = saveAllCursors(pBt, 0, 0);

  }else{
    rc = SQLITE_OK;
  }
  if( tripCode ){
    sqlite3BtreeTripAllCursors(p, tripCode);


  }
  btreeIntegrity(p);

  if( p->inTrans==TRANS_WRITE ){
    int rc2;

    assert( TRANS_WRITE==pBt->inTransaction );







|
|
>

|
|
|

|
|
<
>
|
>
>
|
|
|
>
>
>
>
>
>

|

>
>
>
|
|
|
|
>
>
>
>
>
>
>
>
>
|
|
|
>
|
|
|
|
|
|
|
>
|
>

|
>
>
>
|
<
|




|




>
>



>




|
>
>







56038
56039
56040
56041
56042
56043
56044
56045
56046
56047
56048
56049
56050
56051
56052
56053
56054

56055
56056
56057
56058
56059
56060
56061
56062
56063
56064
56065
56066
56067
56068
56069
56070
56071
56072
56073
56074
56075
56076
56077
56078
56079
56080
56081
56082
56083
56084
56085
56086
56087
56088
56089
56090
56091
56092
56093
56094
56095
56096
56097
56098
56099
56100
56101
56102
56103
56104
56105
56106

56107
56108
56109
56110
56111
56112
56113
56114
56115
56116
56117
56118
56119
56120
56121
56122
56123
56124
56125
56126
56127
56128
56129
56130
56131
56132
56133
56134
56135
56136
  }
  sqlite3BtreeLeave(p);
  return rc;
}

/*
** This routine sets the state to CURSOR_FAULT and the error
** code to errCode for every cursor on any BtShared that pBtree
** references.  Or if the writeOnly flag is set to 1, then only
** trip write cursors and leave read cursors unchanged.
**
** Every cursor is a candidate to be tripped, including cursors
** that belong to other database connections that happen to be
** sharing the cache with pBtree.
**
** This routine gets called when a rollback occurs. If the writeOnly
** flag is true, then only write-cursors need be tripped - read-only

** cursors save their current positions so that they may continue 
** following the rollback. Or, if writeOnly is false, all cursors are 
** tripped. In general, writeOnly is false if the transaction being
** rolled back modified the database schema. In this case b-tree root
** pages may be moved or deleted from the database altogether, making
** it unsafe for read cursors to continue.
**
** If the writeOnly flag is true and an error is encountered while 
** saving the current position of a read-only cursor, all cursors, 
** including all read-cursors are tripped.
**
** SQLITE_OK is returned if successful, or if an error occurs while
** saving a cursor position, an SQLite error code.
*/
SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
  BtCursor *p;
  int rc = SQLITE_OK;

  assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 );
  if( pBtree ){
    sqlite3BtreeEnter(pBtree);
    for(p=pBtree->pBt->pCursor; p; p=p->pNext){
      int i;
      if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
        if( p->eState==CURSOR_VALID ){
          rc = saveCursorPosition(p);
          if( rc!=SQLITE_OK ){
            (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
            break;
          }
        }
      }else{
        sqlite3BtreeClearCursor(p);
        p->eState = CURSOR_FAULT;
        p->skipNext = errCode;
      }
      for(i=0; i<=p->iPage; i++){
        releasePage(p->apPage[i]);
        p->apPage[i] = 0;
      }
    }
    sqlite3BtreeLeave(pBtree);
  }
  return rc;
}

/*
** Rollback the transaction in progress.
**
** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
** Only write cursors are tripped if writeOnly is true but all cursors are
** tripped if writeOnly is false.  Any attempt to use

** a tripped cursor will result in an error.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
  int rc;
  BtShared *pBt = p->pBt;
  MemPage *pPage1;

  assert( writeOnly==1 || writeOnly==0 );
  assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK );
  sqlite3BtreeEnter(p);
  if( tripCode==SQLITE_OK ){
    rc = tripCode = saveAllCursors(pBt, 0, 0);
    if( rc ) writeOnly = 0;
  }else{
    rc = SQLITE_OK;
  }
  if( tripCode ){
    int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly);
    assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) );
    if( rc2!=SQLITE_OK ) rc = rc2;
  }
  btreeIntegrity(p);

  if( p->inTrans==TRANS_WRITE ){
    int rc2;

    assert( TRANS_WRITE==pBt->inTransaction );
55737
55738
55739
55740
55741
55742
55743




55744
55745
55746
55747
55748
55749
55750
  assert( p->inTrans>TRANS_NONE );
  assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
  assert( pBt->pPage1 && pBt->pPage1->aData );

  if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
    return SQLITE_READONLY;
  }




  if( iTable==1 && btreePagecount(pBt)==0 ){
    assert( wrFlag==0 );
    iTable = 0;
  }

  /* Now that no other errors can occur, finish filling in the BtCursor
  ** variables and link the cursor into the BtShared list.  */







>
>
>
>







56289
56290
56291
56292
56293
56294
56295
56296
56297
56298
56299
56300
56301
56302
56303
56304
56305
56306
  assert( p->inTrans>TRANS_NONE );
  assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
  assert( pBt->pPage1 && pBt->pPage1->aData );

  if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
    return SQLITE_READONLY;
  }
  if( wrFlag ){
    allocateTempSpace(pBt);
    if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
  }
  if( iTable==1 && btreePagecount(pBt)==0 ){
    assert( wrFlag==0 );
    iTable = 0;
  }

  /* Now that no other errors can occur, finish filling in the BtCursor
  ** variables and link the cursor into the BtShared list.  */
55901
55902
55903
55904
55905
55906
55907
55908
55909
55910
55911
55912
55913
55914
55915
55916
55917
55918
55919
55920
55921
55922
55923
55924
55925
55926
55927
55928
55929
55930
55931
55932

55933
55934
55935
55936
55937
55938
55939
55940
55941
**
** The caller must position the cursor prior to invoking this routine.
** 
** This routine cannot fail.  It always returns SQLITE_OK.  
*/
SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
  if( pCur->eState!=CURSOR_VALID ){
    *pSize = 0;
  }else{
    getCellInfo(pCur);
    *pSize = pCur->info.nKey;
  }
  return SQLITE_OK;
}

/*
** Set *pSize to the number of bytes of data in the entry the
** cursor currently points to.
**
** The caller must guarantee that the cursor is pointing to a non-NULL
** valid entry.  In other words, the calling procedure must guarantee
** that the cursor has Cursor.eState==CURSOR_VALID.
**
** Failure is not possible.  This function always returns SQLITE_OK.
** It might just as well be a procedure (returning void) but we continue
** to return an integer result code for historical reasons.
*/
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_VALID );

  getCellInfo(pCur);
  *pSize = pCur->info.nData;
  return SQLITE_OK;
}

/*
** Given the page number of an overflow page in the database (parameter
** ovfl), this function finds the page number of the next page in the 
** linked list of overflow pages. If possible, it uses the auto-vacuum







|
<
<
<
|
|
<


















>

|







56457
56458
56459
56460
56461
56462
56463
56464



56465
56466

56467
56468
56469
56470
56471
56472
56473
56474
56475
56476
56477
56478
56479
56480
56481
56482
56483
56484
56485
56486
56487
56488
56489
56490
56491
56492
56493
56494
**
** The caller must position the cursor prior to invoking this routine.
** 
** This routine cannot fail.  It always returns SQLITE_OK.  
*/
SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_VALID );



  getCellInfo(pCur);
  *pSize = pCur->info.nKey;

  return SQLITE_OK;
}

/*
** Set *pSize to the number of bytes of data in the entry the
** cursor currently points to.
**
** The caller must guarantee that the cursor is pointing to a non-NULL
** valid entry.  In other words, the calling procedure must guarantee
** that the cursor has Cursor.eState==CURSOR_VALID.
**
** Failure is not possible.  This function always returns SQLITE_OK.
** It might just as well be a procedure (returning void) but we continue
** to return an integer result code for historical reasons.
*/
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
  getCellInfo(pCur);
  *pSize = pCur->info.nPayload;
  return SQLITE_OK;
}

/*
** Given the page number of an overflow page in the database (parameter
** ovfl), this function finds the page number of the next page in the 
** linked list of overflow pages. If possible, it uses the auto-vacuum
56078
56079
56080
56081
56082
56083
56084
56085
56086
56087
56088
56089

56090
56091
56092
56093
56094
56095
56096
56097
56098
56099
56100
56101
56102
56103
56104

56105
56106
56107
56108
56109
56110
56111
56112
56113
56114
56115
  u32 offset,          /* Begin reading this far into payload */
  u32 amt,             /* Read this many bytes */
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
  int eOp              /* zero to read. non-zero to write. */
){
  unsigned char *aPayload;
  int rc = SQLITE_OK;
  u32 nKey;
  int iIdx = 0;
  MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
  BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
#ifdef SQLITE_DIRECT_OVERFLOW_READ

  int bEnd;                                   /* True if reading to end of data */
#endif

  assert( pPage );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  assert( cursorHoldsMutex(pCur) );
  assert( eOp!=2 || offset==0 );      /* Always start from beginning for eOp==2 */

  getCellInfo(pCur);
  aPayload = pCur->info.pCell + pCur->info.nHeader;
  nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
#ifdef SQLITE_DIRECT_OVERFLOW_READ
  bEnd = (offset+amt==nKey+pCur->info.nData);
#endif


  if( NEVER(offset+amt > nKey+pCur->info.nData) 
   || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
  ){
    /* Trying to read or write past the end of the data is an error */
    return SQLITE_CORRUPT_BKPT;
  }

  /* Check if data must be read/written to/from the btree page itself. */
  if( offset<pCur->info.nLocal ){
    int a = amt;







<




>
|






|


|
<

|

>

<
|
<







56631
56632
56633
56634
56635
56636
56637

56638
56639
56640
56641
56642
56643
56644
56645
56646
56647
56648
56649
56650
56651
56652
56653

56654
56655
56656
56657
56658

56659

56660
56661
56662
56663
56664
56665
56666
  u32 offset,          /* Begin reading this far into payload */
  u32 amt,             /* Read this many bytes */
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
  int eOp              /* zero to read. non-zero to write. */
){
  unsigned char *aPayload;
  int rc = SQLITE_OK;

  int iIdx = 0;
  MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
  BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
#ifdef SQLITE_DIRECT_OVERFLOW_READ
  unsigned char * const pBufStart = pBuf;
  int bEnd;                                 /* True if reading to end of data */
#endif

  assert( pPage );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  assert( cursorHoldsMutex(pCur) );
  assert( eOp!=2 || offset==0 );    /* Always start from beginning for eOp==2 */

  getCellInfo(pCur);
  aPayload = pCur->info.pPayload;

#ifdef SQLITE_DIRECT_OVERFLOW_READ
  bEnd = offset+amt==pCur->info.nPayload;
#endif
  assert( offset+amt <= pCur->info.nPayload );


  if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){

    /* Trying to read or write past the end of the data is an error */
    return SQLITE_CORRUPT_BKPT;
  }

  /* Check if data must be read/written to/from the btree page itself. */
  if( offset<pCur->info.nLocal ){
    int a = amt;
56157
56158
56159
56160
56161
56162
56163
56164


56165
56166
56167
56168
56169
56170
56171
      }
    }

    /* If the overflow page-list cache has been allocated and the
    ** entry for the first required overflow page is valid, skip
    ** directly to it.
    */
    if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){


      iIdx = (offset/ovflSize);
      nextPage = pCur->aOverflow[iIdx];
      offset = (offset%ovflSize);
    }

    for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){








|
>
>







56708
56709
56710
56711
56712
56713
56714
56715
56716
56717
56718
56719
56720
56721
56722
56723
56724
      }
    }

    /* If the overflow page-list cache has been allocated and the
    ** entry for the first required overflow page is valid, skip
    ** directly to it.
    */
    if( (pCur->curFlags & BTCF_ValidOvfl)!=0
     && pCur->aOverflow[offset/ovflSize]
    ){
      iIdx = (offset/ovflSize);
      nextPage = pCur->aOverflow[iIdx];
      offset = (offset%ovflSize);
    }

    for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){

56210
56211
56212
56213
56214
56215
56216

56217
56218
56219
56220
56221
56222
56223
56224
56225
56226
56227

56228
56229
56230

56231
56232
56233
56234
56235
56236
56237
        **
        **   1) this is a read operation, and 
        **   2) data is required from the start of this overflow page, and
        **   3) the database is file-backed, and
        **   4) there is no open write-transaction, and
        **   5) the database is not a WAL database,
        **   6) all data from the page is being read.

        **
        ** then data can be read directly from the database file into the
        ** output buffer, bypassing the page-cache altogether. This speeds
        ** up loading large records that span many overflow pages.
        */
        if( (eOp&0x01)==0                                      /* (1) */
         && offset==0                                          /* (2) */
         && (bEnd || a==ovflSize)                              /* (6) */
         && pBt->inTransaction==TRANS_READ                     /* (4) */
         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
         && pBt->pPage1->aData[19]==0x01                       /* (5) */

        ){
          u8 aSave[4];
          u8 *aWrite = &pBuf[-4];

          memcpy(aSave, aWrite, 4);
          rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
          nextPage = get4byte(aWrite);
          memcpy(aWrite, aSave, 4);
        }else
#endif








>











>



>







56763
56764
56765
56766
56767
56768
56769
56770
56771
56772
56773
56774
56775
56776
56777
56778
56779
56780
56781
56782
56783
56784
56785
56786
56787
56788
56789
56790
56791
56792
56793
        **
        **   1) this is a read operation, and 
        **   2) data is required from the start of this overflow page, and
        **   3) the database is file-backed, and
        **   4) there is no open write-transaction, and
        **   5) the database is not a WAL database,
        **   6) all data from the page is being read.
        **   7) at least 4 bytes have already been read into the output buffer 
        **
        ** then data can be read directly from the database file into the
        ** output buffer, bypassing the page-cache altogether. This speeds
        ** up loading large records that span many overflow pages.
        */
        if( (eOp&0x01)==0                                      /* (1) */
         && offset==0                                          /* (2) */
         && (bEnd || a==ovflSize)                              /* (6) */
         && pBt->inTransaction==TRANS_READ                     /* (4) */
         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
         && pBt->pPage1->aData[19]==0x01                       /* (5) */
         && &pBuf[-4]>=pBufStart                               /* (7) */
        ){
          u8 aSave[4];
          u8 *aWrite = &pBuf[-4];
          assert( aWrite>=pBufStart );                         /* hence (7) */
          memcpy(aSave, aWrite, 4);
          rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
          nextPage = get4byte(aWrite);
          memcpy(aWrite, aSave, 4);
        }else
#endif

56335
56336
56337
56338
56339
56340
56341
56342
56343
56344
56345
56346
56347
56348
56349
  assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
  assert( pCur->eState==CURSOR_VALID );
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
  assert( pCur->info.nSize>0 );
  *pAmt = pCur->info.nLocal;
  return (void*)(pCur->info.pCell + pCur->info.nHeader);
}


/*
** For the entry that cursor pCur is point to, return as
** many bytes of the key or data as are available on the local
** b-tree page.  Write the number of available bytes into *pAmt.







|







56891
56892
56893
56894
56895
56896
56897
56898
56899
56900
56901
56902
56903
56904
56905
  assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
  assert( pCur->eState==CURSOR_VALID );
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
  assert( pCur->info.nSize>0 );
  *pAmt = pCur->info.nLocal;
  return (void*)pCur->info.pPayload;
}


/*
** For the entry that cursor pCur is point to, return as
** many bytes of the key or data as are available on the local
** b-tree page.  Write the number of available bytes into *pAmt.
56763
56764
56765
56766
56767
56768
56769
56770
56771
56772
56773
56774
56775
56776
56777
    assert( biasRight==0 || biasRight==1 );
    idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
    pCur->aiIdx[pCur->iPage] = (u16)idx;
    if( xRecordCompare==0 ){
      for(;;){
        i64 nCellKey;
        pCell = findCell(pPage, idx) + pPage->childPtrSize;
        if( pPage->hasData ){
          while( 0x80 <= *(pCell++) ){
            if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
          }
        }
        getVarint(pCell, (u64*)&nCellKey);
        if( nCellKey<intKey ){
          lwr = idx+1;







|







57319
57320
57321
57322
57323
57324
57325
57326
57327
57328
57329
57330
57331
57332
57333
    assert( biasRight==0 || biasRight==1 );
    idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
    pCur->aiIdx[pCur->iPage] = (u16)idx;
    if( xRecordCompare==0 ){
      for(;;){
        i64 nCellKey;
        pCell = findCell(pPage, idx) + pPage->childPtrSize;
        if( pPage->intKeyLeaf ){
          while( 0x80 <= *(pCell++) ){
            if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
          }
        }
        getVarint(pCell, (u64*)&nCellKey);
        if( nCellKey<intKey ){
          lwr = idx+1;
57022
57023
57024
57025
57026
57027
57028
57029
57030
57031
57032
57033
57034
57035
57036
57037
57038
** Step the cursor to the back to the previous entry in the database.  If
** successful then set *pRes=0.  If the cursor
** was already pointing to the first entry in the database before
** this routine was called, then set *pRes=1.
**
** The main entry point is sqlite3BtreePrevious().  That routine is optimized
** for the common case of merely decrementing the cell counter BtCursor.aiIdx
** to the previous cell on the current page.  The (slower) btreePrevious() helper
** routine is called when it is necessary to move to a different page or
** to restore the cursor.
**
** The calling function will set *pRes to 0 or 1.  The initial *pRes value
** will be 1 if the cursor being stepped corresponds to an SQL index and
** if this routine could have been skipped if that SQL index had been
** a unique index.  Otherwise the caller will have set *pRes to zero.
** Zero is the common case. The btree implementation is free to use the
** initial *pRes value as a hint to improve performance, but the current







|
|
|







57578
57579
57580
57581
57582
57583
57584
57585
57586
57587
57588
57589
57590
57591
57592
57593
57594
** Step the cursor to the back to the previous entry in the database.  If
** successful then set *pRes=0.  If the cursor
** was already pointing to the first entry in the database before
** this routine was called, then set *pRes=1.
**
** The main entry point is sqlite3BtreePrevious().  That routine is optimized
** for the common case of merely decrementing the cell counter BtCursor.aiIdx
** to the previous cell on the current page.  The (slower) btreePrevious()
** helper routine is called when it is necessary to move to a different page
** or to restore the cursor.
**
** The calling function will set *pRes to 0 or 1.  The initial *pRes value
** will be 1 if the cursor being stepped corresponds to an SQL index and
** if this routine could have been skipped if that SQL index had been
** a unique index.  Otherwise the caller will have set *pRes to zero.
** Zero is the common case. The btree implementation is free to use the
** initial *pRes value as a hint to improve performance, but the current
57046
57047
57048
57049
57050
57051
57052
57053
57054
57055
57056
57057
57058
57059
57060
57061
  assert( cursorHoldsMutex(pCur) );
  assert( pRes!=0 );
  assert( *pRes==0 );
  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
  assert( pCur->info.nSize==0 );
  if( pCur->eState!=CURSOR_VALID ){
    assert( pCur->eState>=CURSOR_REQUIRESEEK );
    rc = btreeRestoreCursorPosition(pCur);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    if( CURSOR_INVALID==pCur->eState ){
      *pRes = 1;
      return SQLITE_OK;
    }







<
|







57602
57603
57604
57605
57606
57607
57608

57609
57610
57611
57612
57613
57614
57615
57616
  assert( cursorHoldsMutex(pCur) );
  assert( pRes!=0 );
  assert( *pRes==0 );
  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
  assert( pCur->info.nSize==0 );
  if( pCur->eState!=CURSOR_VALID ){

    rc = restoreCursorPosition(pCur);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    if( CURSOR_INVALID==pCur->eState ){
      *pRes = 1;
      return SQLITE_OK;
    }
57155
57156
57157
57158
57159
57160
57161


57162
57163
57164
57165
57166
57167
57168
  MemPage *pPrevTrunk = 0;
  Pgno mxPage;     /* Total size of the database file */

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
  pPage1 = pBt->pPage1;
  mxPage = btreePagecount(pBt);


  n = get4byte(&pPage1->aData[36]);
  testcase( n==mxPage-1 );
  if( n>=mxPage ){
    return SQLITE_CORRUPT_BKPT;
  }
  if( n>0 ){
    /* There are pages on the freelist.  Reuse one of those pages. */







>
>







57710
57711
57712
57713
57714
57715
57716
57717
57718
57719
57720
57721
57722
57723
57724
57725
  MemPage *pPrevTrunk = 0;
  Pgno mxPage;     /* Total size of the database file */

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
  pPage1 = pBt->pPage1;
  mxPage = btreePagecount(pBt);
  /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36
  ** stores stores the total number of pages on the freelist. */
  n = get4byte(&pPage1->aData[36]);
  testcase( n==mxPage-1 );
  if( n>=mxPage ){
    return SQLITE_CORRUPT_BKPT;
  }
  if( n>0 ){
    /* There are pages on the freelist.  Reuse one of those pages. */
57201
57202
57203
57204
57205
57206
57207



57208
57209



57210
57211
57212
57213
57214
57215
57216
57217
57218
57219
57220
57221
57222
57223
57224

57225
57226
57227
57228
57229
57230
57231
57232
    ** is not true. Otherwise, it runs once for each trunk-page on the
    ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT)
    ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT)
    */
    do {
      pPrevTrunk = pTrunk;
      if( pPrevTrunk ){



        iTrunk = get4byte(&pPrevTrunk->aData[0]);
      }else{



        iTrunk = get4byte(&pPage1->aData[32]);
      }
      testcase( iTrunk==mxPage );
      if( iTrunk>mxPage ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }
      assert( pTrunk!=0 );
      assert( pTrunk->aData!=0 );


      k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
      if( k==0 && !searchList ){
        /* The trunk has no leaves and the list is not being searched. 
        ** So extract the trunk page itself and use it as the newly 
        ** allocated page */
        assert( pPrevTrunk==0 );
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
        if( rc ){







>
>
>


>
>
>














|
>
|







57758
57759
57760
57761
57762
57763
57764
57765
57766
57767
57768
57769
57770
57771
57772
57773
57774
57775
57776
57777
57778
57779
57780
57781
57782
57783
57784
57785
57786
57787
57788
57789
57790
57791
57792
57793
57794
57795
57796
    ** is not true. Otherwise, it runs once for each trunk-page on the
    ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT)
    ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT)
    */
    do {
      pPrevTrunk = pTrunk;
      if( pPrevTrunk ){
        /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page
        ** is the page number of the next freelist trunk page in the list or
        ** zero if this is the last freelist trunk page. */
        iTrunk = get4byte(&pPrevTrunk->aData[0]);
      }else{
        /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32
        ** stores the page number of the first page of the freelist, or zero if
        ** the freelist is empty. */
        iTrunk = get4byte(&pPage1->aData[32]);
      }
      testcase( iTrunk==mxPage );
      if( iTrunk>mxPage ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }
      assert( pTrunk!=0 );
      assert( pTrunk->aData!=0 );
      /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page
      ** is the number of leaf page pointers to follow. */
      k = get4byte(&pTrunk->aData[4]);
      if( k==0 && !searchList ){
        /* The trunk has no leaves and the list is not being searched. 
        ** So extract the trunk page itself and use it as the newly 
        ** allocated page */
        assert( pPrevTrunk==0 );
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
        if( rc ){
57352
57353
57354
57355
57356
57357
57358
57359
57360
57361
57362
57363
57364
57365
57366
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }
          }







|







57916
57917
57918
57919
57920
57921
57922
57923
57924
57925
57926
57927
57928
57929
57930
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }
          }
57385
57386
57387
57388
57389
57390
57391
57392
57393
57394
57395
57396
57397
57398
57399
    **
    ** Note that the pager will not actually attempt to load or journal 
    ** content for any page that really does lie past the end of the database
    ** file on disk. So the effects of disabling the no-content optimization
    ** here are confined to those pages that lie between the end of the
    ** database image and the end of the database file.
    */
    int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;

    rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
    if( rc ) return rc;
    pBt->nPage++;
    if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;

#ifndef SQLITE_OMIT_AUTOVACUUM







|







57949
57950
57951
57952
57953
57954
57955
57956
57957
57958
57959
57960
57961
57962
57963
    **
    ** Note that the pager will not actually attempt to load or journal 
    ** content for any page that really does lie past the end of the database
    ** file on disk. So the effects of disabling the no-content optimization
    ** here are confined to those pages that lie between the end of the
    ** database image and the end of the database file.
    */
    int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0;

    rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
    if( rc ) return rc;
    pBt->nPage++;
    if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;

#ifndef SQLITE_OMIT_AUTOVACUUM
57536
57537
57538
57539
57540
57541
57542





57543
57544
57545
57546
57547
57548
57549
      ** 3.6.0, databases with freelist trunk pages holding more than
      ** usableSize/4 - 8 entries will be reported as corrupt.  In order
      ** to maintain backwards compatibility with older versions of SQLite,
      ** we will continue to restrict the number of entries to usableSize/4 - 8
      ** for now.  At some point in the future (once everyone has upgraded
      ** to 3.6.0 or later) we should consider fixing the conditional above
      ** to read "usableSize/4-2" instead of "usableSize/4-8".





      */
      rc = sqlite3PagerWrite(pTrunk->pDbPage);
      if( rc==SQLITE_OK ){
        put4byte(&pTrunk->aData[4], nLeaf+1);
        put4byte(&pTrunk->aData[8+nLeaf*4], iPage);
        if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){
          sqlite3PagerDontWrite(pPage->pDbPage);







>
>
>
>
>







58100
58101
58102
58103
58104
58105
58106
58107
58108
58109
58110
58111
58112
58113
58114
58115
58116
58117
58118
      ** 3.6.0, databases with freelist trunk pages holding more than
      ** usableSize/4 - 8 entries will be reported as corrupt.  In order
      ** to maintain backwards compatibility with older versions of SQLite,
      ** we will continue to restrict the number of entries to usableSize/4 - 8
      ** for now.  At some point in the future (once everyone has upgraded
      ** to 3.6.0 or later) we should consider fixing the conditional above
      ** to read "usableSize/4-2" instead of "usableSize/4-8".
      **
      ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still
      ** avoid using the last six entries in the freelist trunk page array in
      ** order that database files created by newer versions of SQLite can be
      ** read by older versions of SQLite.
      */
      rc = sqlite3PagerWrite(pTrunk->pDbPage);
      if( rc==SQLITE_OK ){
        put4byte(&pTrunk->aData[4], nLeaf+1);
        put4byte(&pTrunk->aData[8+nLeaf*4], iPage);
        if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){
          sqlite3PagerDontWrite(pPage->pDbPage);
57584
57585
57586
57587
57588
57589
57590
57591


57592
57593




57594
57595
57596
57597
57598
57599
57600
57601
57602

57603
57604
57605
57606
57607
57608
57609
static void freePage(MemPage *pPage, int *pRC){
  if( (*pRC)==SQLITE_OK ){
    *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
  }
}

/*
** Free any overflow pages associated with the given Cell.


*/
static int clearCell(MemPage *pPage, unsigned char *pCell){




  BtShared *pBt = pPage->pBt;
  CellInfo info;
  Pgno ovflPgno;
  int rc;
  int nOvfl;
  u32 ovflPageSize;

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  btreeParseCellPtr(pPage, pCell, &info);

  if( info.iOverflow==0 ){
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  }
  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);







|
>
>

|
>
>
>
>









>







58153
58154
58155
58156
58157
58158
58159
58160
58161
58162
58163
58164
58165
58166
58167
58168
58169
58170
58171
58172
58173
58174
58175
58176
58177
58178
58179
58180
58181
58182
58183
58184
58185
static void freePage(MemPage *pPage, int *pRC){
  if( (*pRC)==SQLITE_OK ){
    *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
  }
}

/*
** Free any overflow pages associated with the given Cell.  Write the
** local Cell size (the number of bytes on the original page, omitting
** overflow) into *pnSize.
*/
static int clearCell(
  MemPage *pPage,          /* The page that contains the Cell */
  unsigned char *pCell,    /* First byte of the Cell */
  u16 *pnSize              /* Write the size of the Cell here */
){
  BtShared *pBt = pPage->pBt;
  CellInfo info;
  Pgno ovflPgno;
  int rc;
  int nOvfl;
  u32 ovflPageSize;

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  btreeParseCellPtr(pPage, pCell, &info);
  *pnSize = info.nSize;
  if( info.iOverflow==0 ){
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  }
  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
57679
57680
57681
57682
57683
57684
57685
57686
57687
57688
57689
57690
57691
57692
57693
57694
57695
57696
57697
57698
57699
57700
57701
57702

57703
57704
57705
57706
57707
57708
57709
57710
57711
57712
57713
57714
57715
57716
57717
57718
57719
57720
57721
57722
57723
57724





57725








57726



57727





















57728
57729



57730
57731
57732
57733
57734
57735
57736
  MemPage *pOvfl = 0;
  MemPage *pToRelease = 0;
  unsigned char *pPrior;
  unsigned char *pPayload;
  BtShared *pBt = pPage->pBt;
  Pgno pgnoOvfl = 0;
  int nHeader;
  CellInfo info;

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );

  /* pPage is not necessarily writeable since pCell might be auxiliary
  ** buffer space that is separate from the pPage buffer area */
  assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
            || sqlite3PagerIswriteable(pPage->pDbPage) );

  /* Fill in the header. */
  nHeader = 0;
  if( !pPage->leaf ){
    nHeader += 4;
  }
  if( pPage->hasData ){
    nHeader += putVarint32(&pCell[nHeader], nData+nZero);
  }else{

    nData = nZero = 0;
  }
  nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
  btreeParseCellPtr(pPage, pCell, &info);
  assert( info.nHeader==nHeader );
  assert( info.nKey==nKey );
  assert( info.nData==(u32)(nData+nZero) );
  
  /* Fill in the payload */
  nPayload = nData + nZero;
  if( pPage->intKey ){
    pSrc = pData;
    nSrc = nData;
    nData = 0;
  }else{ 
    if( NEVER(nKey>0x7fffffff || pKey==0) ){
      return SQLITE_CORRUPT_BKPT;
    }
    nPayload += (int)nKey;
    pSrc = pKey;
    nSrc = (int)nKey;
  }





  *pnSize = info.nSize;








  spaceLeft = info.nLocal;



  pPayload = &pCell[nHeader];





















  pPrior = &pCell[info.iOverflow];




  while( nPayload>0 ){
    if( spaceLeft==0 ){
#ifndef SQLITE_OMIT_AUTOVACUUM
      Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
      if( pBt->autoVacuum ){
        do{
          pgnoOvfl++;







<









|
<
|
<
|
|

>
|


<
<
<
<

|
<








|



>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>







58255
58256
58257
58258
58259
58260
58261

58262
58263
58264
58265
58266
58267
58268
58269
58270
58271

58272

58273
58274
58275
58276
58277
58278
58279




58280
58281

58282
58283
58284
58285
58286
58287
58288
58289
58290
58291
58292
58293
58294
58295
58296
58297
58298
58299
58300
58301
58302
58303
58304
58305
58306
58307
58308
58309
58310
58311
58312
58313
58314
58315
58316
58317
58318
58319
58320
58321
58322
58323
58324
58325
58326
58327
58328
58329
58330
58331
58332
58333
58334
58335
58336
58337
58338
58339
58340
58341
58342
58343
58344
58345
  MemPage *pOvfl = 0;
  MemPage *pToRelease = 0;
  unsigned char *pPrior;
  unsigned char *pPayload;
  BtShared *pBt = pPage->pBt;
  Pgno pgnoOvfl = 0;
  int nHeader;


  assert( sqlite3_mutex_held(pPage->pBt->mutex) );

  /* pPage is not necessarily writeable since pCell might be auxiliary
  ** buffer space that is separate from the pPage buffer area */
  assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
            || sqlite3PagerIswriteable(pPage->pDbPage) );

  /* Fill in the header. */
  nHeader = pPage->childPtrSize;

  nPayload = nData + nZero;

  if( pPage->intKeyLeaf ){
    nHeader += putVarint32(&pCell[nHeader], nPayload);
  }else{
    assert( nData==0 );
    assert( nZero==0 );
  }
  nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);




  
  /* Fill in the payload size */

  if( pPage->intKey ){
    pSrc = pData;
    nSrc = nData;
    nData = 0;
  }else{ 
    if( NEVER(nKey>0x7fffffff || pKey==0) ){
      return SQLITE_CORRUPT_BKPT;
    }
    nPayload = (int)nKey;
    pSrc = pKey;
    nSrc = (int)nKey;
  }
  if( nPayload<=pPage->maxLocal ){
    n = nHeader + nPayload;
    testcase( n==3 );
    testcase( n==4 );
    if( n<4 ) n = 4;
    *pnSize = n;
    spaceLeft = nPayload;
    pPrior = pCell;
  }else{
    int mn = pPage->minLocal;
    n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
    testcase( n==pPage->maxLocal );
    testcase( n==pPage->maxLocal+1 );
    if( n > pPage->maxLocal ) n = mn;
    spaceLeft = n;
    *pnSize = n + nHeader + 4;
    pPrior = &pCell[nHeader+n];
  }
  pPayload = &pCell[nHeader];

  /* At this point variables should be set as follows:
  **
  **   nPayload           Total payload size in bytes
  **   pPayload           Begin writing payload here
  **   spaceLeft          Space available at pPayload.  If nPayload>spaceLeft,
  **                      that means content must spill into overflow pages.
  **   *pnSize            Size of the local cell (not counting overflow pages)
  **   pPrior             Where to write the pgno of the first overflow page
  **
  ** Use a call to btreeParseCellPtr() to verify that the values above
  ** were computed correctly.
  */
#if SQLITE_DEBUG
  {
    CellInfo info;
    btreeParseCellPtr(pPage, pCell, &info);
    assert( nHeader=(int)(info.pPayload - pCell) );
    assert( info.nKey==nKey );
    assert( *pnSize == info.nSize );
    assert( spaceLeft == info.nLocal );
    assert( pPrior == &pCell[info.iOverflow] );
  }
#endif

  /* Write the payload into the local Cell and any extra into overflow pages */
  while( nPayload>0 ){
    if( spaceLeft==0 ){
#ifndef SQLITE_OMIT_AUTOVACUUM
      Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
      if( pBt->autoVacuum ){
        do{
          pgnoOvfl++;
57847
57848
57849
57850
57851
57852
57853







57854
57855
57856

57857
57858
57859
57860
57861
57862
57863
57864
57865
57866
57867
57868
57869
57870
57871
57872
57873
57874
57875
57876
57877
57878
57879
57880
57881
57882
57883
57884
57885
57886
57887
57888
57889
57890
57891
57892
57893
57894
57895
57896
57897
57898
57899
57900
57901
57902
57903
57904
57905
57906
57907
57908
57909
57910
57911
57912
57913
57914
57915
57916
  }
  rc = freeSpace(pPage, pc, sz);
  if( rc ){
    *pRC = rc;
    return;
  }
  pPage->nCell--;







  memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
  put2byte(&data[hdr+3], pPage->nCell);
  pPage->nFree += 2;

}

/*
** Insert a new cell on pPage at cell index "i".  pCell points to the
** content of the cell.
**
** If the cell content will fit on the page, then put it there.  If it
** will not fit, then make a copy of the cell content into pTemp if
** pTemp is not null.  Regardless of pTemp, allocate a new entry
** in pPage->apOvfl[] and make it point to the cell content (either
** in pTemp or the original pCell) and also record its index. 
** Allocating a new entry in pPage->aCell[] implies that 
** pPage->nOverflow is incremented.
**
** If nSkip is non-zero, then do not copy the first nSkip bytes of the
** cell. The caller will overwrite them after this function returns. If
** nSkip is non-zero, then pCell may not point to an invalid memory location 
** (but pCell+nSkip is always valid).
*/
static void insertCell(
  MemPage *pPage,   /* Page into which we are copying */
  int i,            /* New cell becomes the i-th cell of the page */
  u8 *pCell,        /* Content of the new cell */
  int sz,           /* Bytes of content in pCell */
  u8 *pTemp,        /* Temp storage space for pCell, if needed */
  Pgno iChild,      /* If non-zero, replace first 4 bytes with this value */
  int *pRC          /* Read and write return code from here */
){
  int idx = 0;      /* Where to write new cell content in data[] */
  int j;            /* Loop counter */
  int end;          /* First byte past the last cell pointer in data[] */
  int ins;          /* Index in data[] where new cell pointer is inserted */
  int cellOffset;   /* Address of first cell pointer in data[] */
  u8 *data;         /* The content of the whole page */
  int nSkip = (iChild ? 4 : 0);

  if( *pRC ) return;

  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  assert( MX_CELL(pPage->pBt)<=10921 );
  assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
  assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
  assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  /* The cell should normally be sized correctly.  However, when moving a
  ** malformed cell from a leaf page to an interior page, if the cell size
  ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
  ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
  ** the term after the || in the following assert(). */
  assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
  if( pPage->nOverflow || sz+2>pPage->nFree ){
    if( pTemp ){
      memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
      pCell = pTemp;
    }
    if( iChild ){
      put4byte(pCell, iChild);
    }
    j = pPage->nOverflow++;
    assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );







>
>
>
>
>
>
>
|
|
|
>













<
<
<
<
<
















<

















|







58456
58457
58458
58459
58460
58461
58462
58463
58464
58465
58466
58467
58468
58469
58470
58471
58472
58473
58474
58475
58476
58477
58478
58479
58480
58481
58482
58483
58484
58485
58486





58487
58488
58489
58490
58491
58492
58493
58494
58495
58496
58497
58498
58499
58500
58501
58502

58503
58504
58505
58506
58507
58508
58509
58510
58511
58512
58513
58514
58515
58516
58517
58518
58519
58520
58521
58522
58523
58524
58525
58526
58527
  }
  rc = freeSpace(pPage, pc, sz);
  if( rc ){
    *pRC = rc;
    return;
  }
  pPage->nCell--;
  if( pPage->nCell==0 ){
    memset(&data[hdr+1], 0, 4);
    data[hdr+7] = 0;
    put2byte(&data[hdr+5], pPage->pBt->usableSize);
    pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset
                       - pPage->childPtrSize - 8;
  }else{
    memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
    put2byte(&data[hdr+3], pPage->nCell);
    pPage->nFree += 2;
  }
}

/*
** Insert a new cell on pPage at cell index "i".  pCell points to the
** content of the cell.
**
** If the cell content will fit on the page, then put it there.  If it
** will not fit, then make a copy of the cell content into pTemp if
** pTemp is not null.  Regardless of pTemp, allocate a new entry
** in pPage->apOvfl[] and make it point to the cell content (either
** in pTemp or the original pCell) and also record its index. 
** Allocating a new entry in pPage->aCell[] implies that 
** pPage->nOverflow is incremented.





*/
static void insertCell(
  MemPage *pPage,   /* Page into which we are copying */
  int i,            /* New cell becomes the i-th cell of the page */
  u8 *pCell,        /* Content of the new cell */
  int sz,           /* Bytes of content in pCell */
  u8 *pTemp,        /* Temp storage space for pCell, if needed */
  Pgno iChild,      /* If non-zero, replace first 4 bytes with this value */
  int *pRC          /* Read and write return code from here */
){
  int idx = 0;      /* Where to write new cell content in data[] */
  int j;            /* Loop counter */
  int end;          /* First byte past the last cell pointer in data[] */
  int ins;          /* Index in data[] where new cell pointer is inserted */
  int cellOffset;   /* Address of first cell pointer in data[] */
  u8 *data;         /* The content of the whole page */


  if( *pRC ) return;

  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  assert( MX_CELL(pPage->pBt)<=10921 );
  assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
  assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
  assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  /* The cell should normally be sized correctly.  However, when moving a
  ** malformed cell from a leaf page to an interior page, if the cell size
  ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
  ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
  ** the term after the || in the following assert(). */
  assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
  if( pPage->nOverflow || sz+2>pPage->nFree ){
    if( pTemp ){
      memcpy(pTemp, pCell, sz);
      pCell = pTemp;
    }
    if( iChild ){
      put4byte(pCell, iChild);
    }
    j = pPage->nOverflow++;
    assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
57931
57932
57933
57934
57935
57936
57937
57938
57939
57940
57941
57942
57943
57944
57945
57946
57947
57948
57949
57950
57951
57952
57953
57954
57955
57956


























57957


57958















































57959
57960
57961



57962
57963
57964
57965
57966
57967
57968
57969
57970



57971





57972







57973
















57974


57975

57976
57977








57978
















57979





























57980




57981







57982





57983


57984










57985

57986




57987








57988



57989


57990


57991
57992
57993
57994










57995




57996
57997
57998
57999
58000
58001
58002
    if( rc ){ *pRC = rc; return; }
    /* The allocateSpace() routine guarantees the following two properties
    ** if it returns success */
    assert( idx >= end+2 );
    assert( idx+sz <= (int)pPage->pBt->usableSize );
    pPage->nCell++;
    pPage->nFree -= (u16)(2 + sz);
    memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
    if( iChild ){
      put4byte(&data[idx], iChild);
    }
    memmove(&data[ins+2], &data[ins], end-ins);
    put2byte(&data[ins], idx);
    put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pPage->pBt->autoVacuum ){
      /* The cell may contain a pointer to an overflow page. If so, write
      ** the entry for the overflow page into the pointer map.
      */
      ptrmapPutOvflPtr(pPage, pCell, pRC);
    }
#endif
  }
}

/*


























** Add a list of cells to a page.  The page should be initially empty.


** The cells are guaranteed to fit on the page.















































*/
static void assemblePage(
  MemPage *pPage,   /* The page to be assembled */



  int nCell,        /* The number of cells to add to this page */
  u8 **apCell,      /* Pointers to cell bodies */
  u16 *aSize        /* Sizes of the cells */
){
  int i;            /* Loop counter */
  u8 *pCellptr;     /* Address of next cell pointer */
  int cellbody;     /* Address of next cell body */
  u8 * const data = pPage->aData;             /* Pointer to data for pPage */
  const int hdr = pPage->hdrOffset;           /* Offset of header on pPage */



  const int nUsable = pPage->pBt->usableSize; /* Usable size of page */













  assert( pPage->nOverflow==0 );
















  assert( sqlite3_mutex_held(pPage->pBt->mutex) );


  assert( nCell>=0 && nCell<=(int)MX_CELL(pPage->pBt)

            && (int)MX_CELL(pPage->pBt)<=10921);
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );

























  /* Check that the page has just been zeroed by zeroPage() */





























  assert( pPage->nCell==0 );




  assert( get2byteNotZero(&data[hdr+5])==nUsable );













  pCellptr = &pPage->aCellIdx[nCell*2];


  cellbody = nUsable;










  for(i=nCell-1; i>=0; i--){

    u16 sz = aSize[i];




    pCellptr -= 2;








    cellbody -= sz;



    put2byte(pCellptr, cellbody);


    memcpy(&data[cellbody], apCell[i], sz);


  }
  put2byte(&data[hdr+3], nCell);
  put2byte(&data[hdr+5], cellbody);
  pPage->nFree -= (nCell*2 + nUsable - cellbody);










  pPage->nCell = (u16)nCell;




}

/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the
** total number of pages that participate, including the target page and







|


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
>
>
>
|
|
|

|
|
<
|
|
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
|
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
|
>
>
|
|
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>







58542
58543
58544
58545
58546
58547
58548
58549
58550
58551
58552
58553
58554
58555
58556
58557
58558
58559
58560
58561
58562
58563
58564
58565
58566
58567
58568
58569
58570
58571
58572
58573
58574
58575
58576
58577
58578
58579
58580
58581
58582
58583
58584
58585
58586
58587
58588
58589
58590
58591
58592
58593
58594
58595
58596
58597
58598
58599
58600
58601
58602
58603
58604
58605
58606
58607
58608
58609
58610
58611
58612
58613
58614
58615
58616
58617
58618
58619
58620
58621
58622
58623
58624
58625
58626
58627
58628
58629
58630
58631
58632
58633
58634
58635
58636
58637
58638
58639
58640
58641
58642
58643
58644
58645
58646
58647
58648
58649
58650
58651
58652
58653
58654
58655
58656

58657
58658
58659
58660
58661
58662
58663
58664
58665
58666
58667
58668
58669
58670
58671
58672
58673
58674
58675
58676
58677
58678
58679
58680
58681
58682
58683
58684
58685
58686
58687
58688
58689
58690
58691
58692
58693
58694
58695
58696
58697
58698
58699
58700
58701
58702
58703
58704
58705
58706
58707
58708
58709
58710
58711
58712
58713
58714
58715
58716
58717
58718
58719
58720
58721
58722
58723
58724
58725
58726
58727
58728
58729
58730
58731
58732
58733
58734
58735
58736
58737
58738
58739
58740
58741
58742
58743
58744
58745
58746
58747
58748
58749
58750
58751
58752
58753
58754
58755
58756
58757
58758
58759
58760
58761
58762
58763
58764
58765
58766
58767
58768
58769
58770
58771
58772
58773
58774
58775
58776
58777
58778
58779
58780
58781
58782
58783
58784
58785
58786
58787
58788
58789
58790
58791
58792
58793
58794
58795
58796
58797
58798
58799
58800
58801
58802
58803
58804
58805
58806
58807
58808
58809
58810
58811
58812
58813
58814
58815
58816
58817
58818
58819
58820
58821
58822
58823
58824
58825
58826
58827
58828
58829
58830
58831
58832
58833
58834
58835
58836
58837
58838
58839
    if( rc ){ *pRC = rc; return; }
    /* The allocateSpace() routine guarantees the following two properties
    ** if it returns success */
    assert( idx >= end+2 );
    assert( idx+sz <= (int)pPage->pBt->usableSize );
    pPage->nCell++;
    pPage->nFree -= (u16)(2 + sz);
    memcpy(&data[idx], pCell, sz);
    if( iChild ){
      put4byte(&data[idx], iChild);
    }
    memmove(&data[ins+2], &data[ins], end-ins);
    put2byte(&data[ins], idx);
    put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pPage->pBt->autoVacuum ){
      /* The cell may contain a pointer to an overflow page. If so, write
      ** the entry for the overflow page into the pointer map.
      */
      ptrmapPutOvflPtr(pPage, pCell, pRC);
    }
#endif
  }
}

/*
** Array apCell[] contains pointers to nCell b-tree page cells. The 
** szCell[] array contains the size in bytes of each cell. This function
** replaces the current contents of page pPg with the contents of the cell
** array.
**
** Some of the cells in apCell[] may currently be stored in pPg. This
** function works around problems caused by this by making a copy of any 
** such cells before overwriting the page data.
**
** The MemPage.nFree field is invalidated by this function. It is the 
** responsibility of the caller to set it correctly.
*/
static void rebuildPage(
  MemPage *pPg,                   /* Edit this page */
  int nCell,                      /* Final number of cells on page */
  u8 **apCell,                    /* Array of cells */
  u16 *szCell                     /* Array of cell sizes */
){
  const int hdr = pPg->hdrOffset;          /* Offset of header on pPg */
  u8 * const aData = pPg->aData;           /* Pointer to data for pPg */
  const int usableSize = pPg->pBt->usableSize;
  u8 * const pEnd = &aData[usableSize];
  int i;
  u8 *pCellptr = pPg->aCellIdx;
  u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
  u8 *pData;

  i = get2byte(&aData[hdr+5]);
  memcpy(&pTmp[i], &aData[i], usableSize - i);

  pData = pEnd;
  for(i=0; i<nCell; i++){
    u8 *pCell = apCell[i];
    if( pCell>aData && pCell<pEnd ){
      pCell = &pTmp[pCell - aData];
    }
    pData -= szCell[i];
    memcpy(pData, pCell, szCell[i]);
    put2byte(pCellptr, (pData - aData));
    pCellptr += 2;
    assert( szCell[i]==cellSizePtr(pPg, pCell) );
  }

  /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
  pPg->nCell = nCell;
  pPg->nOverflow = 0;

  put2byte(&aData[hdr+1], 0);
  put2byte(&aData[hdr+3], pPg->nCell);
  put2byte(&aData[hdr+5], pData - aData);
  aData[hdr+7] = 0x00;
}

/*
** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
** contains the size in bytes of each such cell. This function attempts to 
** add the cells stored in the array to page pPg. If it cannot (because 
** the page needs to be defragmented before the cells will fit), non-zero
** is returned. Otherwise, if the cells are added successfully, zero is
** returned.
**
** Argument pCellptr points to the first entry in the cell-pointer array
** (part of page pPg) to populate. After cell apCell[0] is written to the
** page body, a 16-bit offset is written to pCellptr. And so on, for each
** cell in the array. It is the responsibility of the caller to ensure
** that it is safe to overwrite this part of the cell-pointer array.
**
** When this function is called, *ppData points to the start of the 
** content area on page pPg. If the size of the content area is extended,
** *ppData is updated to point to the new start of the content area
** before returning.
**
** Finally, argument pBegin points to the byte immediately following the
** end of the space required by this page for the cell-pointer area (for
** all cells - not just those inserted by the current call). If the content
** area must be extended to before this point in order to accomodate all
** cells in apCell[], then the cells do not fit and non-zero is returned.
*/
static int pageInsertArray(
  MemPage *pPg,                   /* Page to add cells to */
  u8 *pBegin,                     /* End of cell-pointer array */
  u8 **ppData,                    /* IN/OUT: Page content -area pointer */
  u8 *pCellptr,                   /* Pointer to cell-pointer area */
  int nCell,                      /* Number of cells to add to pPg */
  u8 **apCell,                    /* Array of cells */
  u16 *szCell                     /* Array of cell sizes */
){
  int i;
  u8 *aData = pPg->aData;

  u8 *pData = *ppData;
  const int bFreelist = aData[1] || aData[2];
  assert( CORRUPT_DB || pPg->hdrOffset==0 );    /* Never called on page 1 */
  for(i=0; i<nCell; i++){
    int sz = szCell[i];
    int rc;
    u8 *pSlot;
    if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, &rc, 0))==0 ){
      pData -= sz;
      if( pData<pBegin ) return 1;
      pSlot = pData;
    }
    memcpy(pSlot, apCell[i], sz);
    put2byte(pCellptr, (pSlot - aData));
    pCellptr += 2;
  }
  *ppData = pData;
  return 0;
}

/*
** Array apCell[] contains nCell pointers to b-tree cells. Array szCell 
** contains the size in bytes of each such cell. This function adds the
** space associated with each cell in the array that is currently stored 
** within the body of pPg to the pPg free-list. The cell-pointers and other
** fields of the page are not updated.
**
** This function returns the total number of cells added to the free-list.
*/
static int pageFreeArray(
  MemPage *pPg,                   /* Page to edit */
  int nCell,                      /* Cells to delete */
  u8 **apCell,                    /* Array of cells */
  u16 *szCell                     /* Array of cell sizes */
){
  u8 * const aData = pPg->aData;
  u8 * const pEnd = &aData[pPg->pBt->usableSize];
  u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
  int nRet = 0;
  int i;
  u8 *pFree = 0;
  int szFree = 0;

  for(i=0; i<nCell; i++){
    u8 *pCell = apCell[i];
    if( pCell>=pStart && pCell<pEnd ){
      int sz = szCell[i];
      if( pFree!=(pCell + sz) ){
        if( pFree ){
          assert( pFree>aData && (pFree - aData)<65536 );
          freeSpace(pPg, (u16)(pFree - aData), szFree);
        }
        pFree = pCell;
        szFree = sz;
        if( pFree+sz>pEnd ) return 0;
      }else{
        pFree = pCell;
        szFree += sz;
      }
      nRet++;
    }
  }
  if( pFree ){
    assert( pFree>aData && (pFree - aData)<65536 );
    freeSpace(pPg, (u16)(pFree - aData), szFree);
  }
  return nRet;
}

/*
** apCell[] and szCell[] contains pointers to and sizes of all cells in the
** pages being balanced.  The current page, pPg, has pPg->nCell cells starting
** with apCell[iOld].  After balancing, this page should hold nNew cells
** starting at apCell[iNew].
**
** This routine makes the necessary adjustments to pPg so that it contains
** the correct cells after being balanced.
**
** The pPg->nFree field is invalid when this function returns. It is the
** responsibility of the caller to set it correctly.
*/
static void editPage(
  MemPage *pPg,                   /* Edit this page */
  int iOld,                       /* Index of first cell currently on page */
  int iNew,                       /* Index of new first cell on page */
  int nNew,                       /* Final number of cells on page */
  u8 **apCell,                    /* Array of cells */
  u16 *szCell                     /* Array of cell sizes */
){
  u8 * const aData = pPg->aData;
  const int hdr = pPg->hdrOffset;
  u8 *pBegin = &pPg->aCellIdx[nNew * 2];
  int nCell = pPg->nCell;       /* Cells stored on pPg */
  u8 *pData;
  u8 *pCellptr;
  int i;
  int iOldEnd = iOld + pPg->nCell + pPg->nOverflow;
  int iNewEnd = iNew + nNew;

#ifdef SQLITE_DEBUG
  u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
  memcpy(pTmp, aData, pPg->pBt->usableSize);
#endif

  /* Remove cells from the start and end of the page */
  if( iOld<iNew ){
    int nShift = pageFreeArray(
        pPg, iNew-iOld, &apCell[iOld], &szCell[iOld]
    );
    memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
    nCell -= nShift;
  }
  if( iNewEnd < iOldEnd ){
    nCell -= pageFreeArray(
        pPg, iOldEnd-iNewEnd, &apCell[iNewEnd], &szCell[iNewEnd]
    );
  }

  pData = &aData[get2byteNotZero(&aData[hdr+5])];
  if( pData<pBegin ) goto editpage_fail;

  /* Add cells to the start of the page */
  if( iNew<iOld ){
    int nAdd = MIN(nNew,iOld-iNew);
    assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
    pCellptr = pPg->aCellIdx;
    memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
    if( pageInsertArray(
          pPg, pBegin, &pData, pCellptr,
          nAdd, &apCell[iNew], &szCell[iNew]
    ) ) goto editpage_fail;
    nCell += nAdd;
  }

  /* Add any overflow cells */
  for(i=0; i<pPg->nOverflow; i++){
    int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
    if( iCell>=0 && iCell<nNew ){
      pCellptr = &pPg->aCellIdx[iCell * 2];
      memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
      nCell++;
      if( pageInsertArray(
            pPg, pBegin, &pData, pCellptr,
            1, &apCell[iCell + iNew], &szCell[iCell + iNew]
      ) ) goto editpage_fail;
    }
  }

  /* Append cells to the end of the page */
  pCellptr = &pPg->aCellIdx[nCell*2];
  if( pageInsertArray(
        pPg, pBegin, &pData, pCellptr,
        nNew-nCell, &apCell[iNew+nCell], &szCell[iNew+nCell]
  ) ) goto editpage_fail;

  pPg->nCell = nNew;
  pPg->nOverflow = 0;

  put2byte(&aData[hdr+3], pPg->nCell);
  put2byte(&aData[hdr+5], pData - aData);

#ifdef SQLITE_DEBUG
  for(i=0; i<nNew && !CORRUPT_DB; i++){
    u8 *pCell = apCell[i+iNew];
    int iOff = get2byte(&pPg->aCellIdx[i*2]);
    if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
      pCell = &pTmp[pCell - aData];
    }
    assert( 0==memcmp(pCell, &aData[iOff], szCell[i+iNew]) );
  }
#endif

  return;
 editpage_fail:
  /* Unable to edit this page. Rebuild it from scratch instead. */
  rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]);
}

/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the
** total number of pages that participate, including the target page and
58060
58061
58062
58063
58064
58065
58066
58067

58068
58069
58070
58071
58072
58073
58074
    u8 *pCell = pPage->apOvfl[0];
    u16 szCell = cellSizePtr(pPage, pCell);
    u8 *pStop;

    assert( sqlite3PagerIswriteable(pNew->pDbPage) );
    assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
    zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
    assemblePage(pNew, 1, &pCell, &szCell);


    /* If this is an auto-vacuum database, update the pointer map
    ** with entries for the new page, and any pointer from the 
    ** cell on the page to an overflow page. If either of these
    ** operations fails, the return code is set, but the contents
    ** of the parent page are still manipulated by thh code below.
    ** That is Ok, at this point the parent page is guaranteed to







|
>







58897
58898
58899
58900
58901
58902
58903
58904
58905
58906
58907
58908
58909
58910
58911
58912
    u8 *pCell = pPage->apOvfl[0];
    u16 szCell = cellSizePtr(pPage, pCell);
    u8 *pStop;

    assert( sqlite3PagerIswriteable(pNew->pDbPage) );
    assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
    zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
    rebuildPage(pNew, 1, &pCell, &szCell);
    pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;

    /* If this is an auto-vacuum database, update the pointer map
    ** with entries for the new page, and any pointer from the 
    ** cell on the page to an overflow page. If either of these
    ** operations fails, the return code is set, but the contents
    ** of the parent page are still manipulated by thh code below.
    ** That is Ok, at this point the parent page is guaranteed to
58279
58280
58281
58282
58283
58284
58285
58286
58287
58288
58289
58290

58291
58292
58293
58294
58295




58296

58297
58298
58299
58300
58301
58302
58303
  int usableSpace;             /* Bytes in pPage beyond the header */
  int pageFlags;               /* Value of pPage->aData[0] */
  int subtotal;                /* Subtotal of bytes in cells on one page */
  int iSpace1 = 0;             /* First unused byte of aSpace1[] */
  int iOvflSpace = 0;          /* First unused byte of aOvflSpace[] */
  int szScratch;               /* Size of scratch memory requested */
  MemPage *apOld[NB];          /* pPage and up to two siblings */
  MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
  MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
  u8 *pRight;                  /* Location in parent of right-sibling pointer */
  u8 *apDiv[NB-1];             /* Divider cells in pParent */
  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */

  int szNew[NB+2];             /* Combined size of cells place on i-th page */
  u8 **apCell = 0;             /* All cells begin balanced */
  u16 *szCell;                 /* Local size of all cells in apCell[] */
  u8 *aSpace1;                 /* Space for copies of dividers cells */
  Pgno pgno;                   /* Temp var to store a page number in */






  pBt = pParent->pBt;
  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( sqlite3PagerIswriteable(pParent->pDbPage) );

#if 0
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
#endif







<




>
|




>
>
>
>

>







59117
59118
59119
59120
59121
59122
59123

59124
59125
59126
59127
59128
59129
59130
59131
59132
59133
59134
59135
59136
59137
59138
59139
59140
59141
59142
59143
59144
59145
59146
  int usableSpace;             /* Bytes in pPage beyond the header */
  int pageFlags;               /* Value of pPage->aData[0] */
  int subtotal;                /* Subtotal of bytes in cells on one page */
  int iSpace1 = 0;             /* First unused byte of aSpace1[] */
  int iOvflSpace = 0;          /* First unused byte of aOvflSpace[] */
  int szScratch;               /* Size of scratch memory requested */
  MemPage *apOld[NB];          /* pPage and up to two siblings */

  MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
  u8 *pRight;                  /* Location in parent of right-sibling pointer */
  u8 *apDiv[NB-1];             /* Divider cells in pParent */
  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
  int cntOld[NB+2];            /* Old index in aCell[] after i-th page */
  int szNew[NB+2];             /* Combined size of cells placed on i-th page */
  u8 **apCell = 0;             /* All cells begin balanced */
  u16 *szCell;                 /* Local size of all cells in apCell[] */
  u8 *aSpace1;                 /* Space for copies of dividers cells */
  Pgno pgno;                   /* Temp var to store a page number in */
  u8 abDone[NB+2];             /* True after i'th new page is populated */
  Pgno aPgno[NB+2];            /* Page numbers of new pages before shuffling */
  Pgno aPgOrder[NB+2];         /* Copy of aPgno[] used for sorting pages */
  u16 aPgFlags[NB+2];          /* flags field of new pages before shuffling */

  memset(abDone, 0, sizeof(abDone));
  pBt = pParent->pBt;
  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( sqlite3PagerIswriteable(pParent->pDbPage) );

#if 0
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
#endif
58398
58399
58400
58401
58402
58403
58404
58405
58406
58407
58408
58409
58410



58411
58412
58413
58414
58415
58416
58417
58418
58419
58420
58421
58422
58423
58424
58425
58426
58427
58428
58429
58430
58431
58432
58433
58434
58435
58436
58437
58438
58439
58440
58441
58442
58443
58444
58445
58446
58447
58448
58449
58450
58451
58452
58453
58454
58455
58456
58457
58458
58459
58460
58461
58462
58463
58464
58465
58466
58467
58468

58469
58470
58471
58472
58473
58474
58475
  /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
  ** alignment */
  nMaxCells = (nMaxCells + 3)&~3;

  /*
  ** Allocate space for memory structures
  */
  k = pBt->pageSize + ROUND8(sizeof(MemPage));
  szScratch =
       nMaxCells*sizeof(u8*)                       /* apCell */
     + nMaxCells*sizeof(u16)                       /* szCell */
     + pBt->pageSize                               /* aSpace1 */
     + k*nOld;                                     /* Page copies (apCopy) */



  apCell = sqlite3ScratchMalloc( szScratch ); 
  if( apCell==0 ){
    rc = SQLITE_NOMEM;
    goto balance_cleanup;
  }
  szCell = (u16*)&apCell[nMaxCells];
  aSpace1 = (u8*)&szCell[nMaxCells];
  assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );

  /*
  ** Load pointers to all cells on sibling pages and the divider cells
  ** into the local apCell[] array.  Make copies of the divider cells
  ** into space obtained from aSpace1[] and remove the divider cells
  ** from pParent.
  **
  ** If the siblings are on leaf pages, then the child pointers of the
  ** divider cells are stripped from the cells before they are copied
  ** into aSpace1[].  In this way, all cells in apCell[] are without
  ** child pointers.  If siblings are not leaves, then all cell in
  ** apCell[] include child pointers.  Either way, all cells in apCell[]
  ** are alike.
  **
  ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
  **       leafData:  1 if pPage holds key+data and pParent holds only keys.
  */
  leafCorrection = apOld[0]->leaf*4;
  leafData = apOld[0]->hasData;
  for(i=0; i<nOld; i++){
    int limit;
    
    /* Before doing anything else, take a copy of the i'th original sibling
    ** The rest of this function will use data from the copies rather
    ** that the original pages since the original pages will be in the
    ** process of being overwritten.  */
    MemPage *pOld = apCopy[i] = (MemPage*)&aSpace1[pBt->pageSize + k*i];
    memcpy(pOld, apOld[i], sizeof(MemPage));
    pOld->aData = (void*)&pOld[1];
    memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize);

    limit = pOld->nCell+pOld->nOverflow;
    if( pOld->nOverflow>0 ){
      for(j=0; j<limit; j++){
        assert( nCell<nMaxCells );
        apCell[nCell] = findOverflowCell(pOld, j);
        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
        nCell++;
      }
    }else{
      u8 *aData = pOld->aData;
      u16 maskPage = pOld->maskPage;
      u16 cellOffset = pOld->cellOffset;
      for(j=0; j<limit; j++){
        assert( nCell<nMaxCells );
        apCell[nCell] = findCellv2(aData, maskPage, cellOffset, j);
        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
        nCell++;
      }
    }       

    if( i<nOld-1 && !leafData){
      u16 sz = (u16)szNew[i];
      u8 *pTemp;
      assert( nCell<nMaxCells );
      szCell[nCell] = sz;
      pTemp = &aSpace1[iSpace1];
      iSpace1 += sz;







<



|
|
>
>
>












|
|












|


<
<
<
<
<
|
<
<
<




















>







59241
59242
59243
59244
59245
59246
59247

59248
59249
59250
59251
59252
59253
59254
59255
59256
59257
59258
59259
59260
59261
59262
59263
59264
59265
59266
59267
59268
59269
59270
59271
59272
59273
59274
59275
59276
59277
59278
59279
59280
59281
59282
59283
59284





59285



59286
59287
59288
59289
59290
59291
59292
59293
59294
59295
59296
59297
59298
59299
59300
59301
59302
59303
59304
59305
59306
59307
59308
59309
59310
59311
59312
59313
  /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
  ** alignment */
  nMaxCells = (nMaxCells + 3)&~3;

  /*
  ** Allocate space for memory structures
  */

  szScratch =
       nMaxCells*sizeof(u8*)                       /* apCell */
     + nMaxCells*sizeof(u16)                       /* szCell */
     + pBt->pageSize;                              /* aSpace1 */

  /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
  ** that is more than 6 times the database page size. */
  assert( szScratch<=6*pBt->pageSize );
  apCell = sqlite3ScratchMalloc( szScratch ); 
  if( apCell==0 ){
    rc = SQLITE_NOMEM;
    goto balance_cleanup;
  }
  szCell = (u16*)&apCell[nMaxCells];
  aSpace1 = (u8*)&szCell[nMaxCells];
  assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );

  /*
  ** Load pointers to all cells on sibling pages and the divider cells
  ** into the local apCell[] array.  Make copies of the divider cells
  ** into space obtained from aSpace1[]. The divider cells have already
  ** been removed from pParent.
  **
  ** If the siblings are on leaf pages, then the child pointers of the
  ** divider cells are stripped from the cells before they are copied
  ** into aSpace1[].  In this way, all cells in apCell[] are without
  ** child pointers.  If siblings are not leaves, then all cell in
  ** apCell[] include child pointers.  Either way, all cells in apCell[]
  ** are alike.
  **
  ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
  **       leafData:  1 if pPage holds key+data and pParent holds only keys.
  */
  leafCorrection = apOld[0]->leaf*4;
  leafData = apOld[0]->intKeyLeaf;
  for(i=0; i<nOld; i++){
    int limit;





    MemPage *pOld = apOld[i];




    limit = pOld->nCell+pOld->nOverflow;
    if( pOld->nOverflow>0 ){
      for(j=0; j<limit; j++){
        assert( nCell<nMaxCells );
        apCell[nCell] = findOverflowCell(pOld, j);
        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
        nCell++;
      }
    }else{
      u8 *aData = pOld->aData;
      u16 maskPage = pOld->maskPage;
      u16 cellOffset = pOld->cellOffset;
      for(j=0; j<limit; j++){
        assert( nCell<nMaxCells );
        apCell[nCell] = findCellv2(aData, maskPage, cellOffset, j);
        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
        nCell++;
      }
    }       
    cntOld[i] = nCell;
    if( i<nOld-1 && !leafData){
      u16 sz = (u16)szNew[i];
      u8 *pTemp;
      assert( nCell<nMaxCells );
      szCell[nCell] = sz;
      pTemp = &aSpace1[iSpace1];
      iSpace1 += sz;
58513
58514
58515
58516
58517
58518
58519
58520
58521
58522
58523
58524
58525
58526
58527
58528
58529
58530
58531
58532
58533
58534
58535

58536
58537
58538
58539
58540
58541
58542
58543
  ** 
  */
  usableSpace = pBt->usableSize - 12 + leafCorrection;
  for(subtotal=k=i=0; i<nCell; i++){
    assert( i<nMaxCells );
    subtotal += szCell[i] + 2;
    if( subtotal > usableSpace ){
      szNew[k] = subtotal - szCell[i];
      cntNew[k] = i;
      if( leafData ){ i--; }
      subtotal = 0;
      k++;
      if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
    }
  }
  szNew[k] = subtotal;
  cntNew[k] = nCell;
  k++;

  /*
  ** The packing computed by the previous block is biased toward the siblings
  ** on the left side.  The left siblings are always nearly full, while the
  ** right-most sibling might be nearly empty.  This block of code attempts

  ** to adjust the packing of siblings to get a better balance.
  **
  ** This adjustment is more than an optimization.  The packing above might
  ** be so out of balance as to be illegal.  For example, the right-most
  ** sibling might be completely empty.  This adjustment is not optional.
  */
  for(i=k-1; i>0; i--){
    int szRight = szNew[i];  /* Size of sibling on the right */







|













|
|
>
|







59351
59352
59353
59354
59355
59356
59357
59358
59359
59360
59361
59362
59363
59364
59365
59366
59367
59368
59369
59370
59371
59372
59373
59374
59375
59376
59377
59378
59379
59380
59381
59382
  ** 
  */
  usableSpace = pBt->usableSize - 12 + leafCorrection;
  for(subtotal=k=i=0; i<nCell; i++){
    assert( i<nMaxCells );
    subtotal += szCell[i] + 2;
    if( subtotal > usableSpace ){
      szNew[k] = subtotal - szCell[i] - 2;
      cntNew[k] = i;
      if( leafData ){ i--; }
      subtotal = 0;
      k++;
      if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
    }
  }
  szNew[k] = subtotal;
  cntNew[k] = nCell;
  k++;

  /*
  ** The packing computed by the previous block is biased toward the siblings
  ** on the left side (siblings with smaller keys). The left siblings are
  ** always nearly full, while the right-most sibling might be nearly empty.
  ** The next block of code attempts to adjust the packing of siblings to
  ** get a better balance.
  **
  ** This adjustment is more than an optimization.  The packing above might
  ** be so out of balance as to be illegal.  For example, the right-most
  ** sibling might be completely empty.  This adjustment is not optional.
  */
  for(i=k-1; i>0; i--){
    int szRight = szNew[i];  /* Size of sibling on the right */
58558
58559
58560
58561
58562
58563
58564


58565
58566
58567
58568
58569
58570
58571
58572
58573
58574
58575
58576
58577
58578
58579
58580
58581
58582
58583
58584
58585
58586
58587
      r = cntNew[i-1] - 1;
      d = r + 1 - leafData;
    }
    szNew[i] = szRight;
    szNew[i-1] = szLeft;
  }



  /* Either we found one or more cells (cntnew[0])>0) or pPage is
  ** a virtual root page.  A virtual root page is when the real root
  ** page is page 1 and we are the only child of that page.
  **
  ** UPDATE:  The assert() below is not necessarily true if the database
  ** file is corrupt.  The corruption will be detected and reported later
  ** in this procedure so there is no need to act upon it now.
  */
#if 0
  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
#endif

  TRACE(("BALANCE: old: %d %d %d  ",
    apOld[0]->pgno, 
    nOld>=2 ? apOld[1]->pgno : 0,
    nOld>=3 ? apOld[2]->pgno : 0
  ));

  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */
  if( apOld[0]->pgno<=1 ){
    rc = SQLITE_CORRUPT_BKPT;







>
>
|
|
|
|
<
<
<

<
|
<
<
|
|
|
|







59397
59398
59399
59400
59401
59402
59403
59404
59405
59406
59407
59408
59409



59410

59411


59412
59413
59414
59415
59416
59417
59418
59419
59420
59421
59422
      r = cntNew[i-1] - 1;
      d = r + 1 - leafData;
    }
    szNew[i] = szRight;
    szNew[i-1] = szLeft;
  }

  /* Sanity check:  For a non-corrupt database file one of the follwing
  ** must be true:
  **    (1) We found one or more cells (cntNew[0])>0), or
  **    (2) pPage is a virtual root page.  A virtual root page is when
  **        the real root page is page 1 and we are the only child of
  **        that page.



  */

  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB);


  TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n",
    apOld[0]->pgno, apOld[0]->nCell,
    nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0,
    nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0
  ));

  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */
  if( apOld[0]->pgno<=1 ){
    rc = SQLITE_CORRUPT_BKPT;
58596
58597
58598
58599
58600
58601
58602

58603
58604

58605
58606
58607
58608
58609
58610
58611
58612
58613
58614
58615
58616
58617
58618
58619
58620
58621
58622
58623
58624
58625
58626
58627
58628
58629
58630
58631
58632
58633
58634
58635
58636
58637
58638
58639
58640

58641









58642




58643

58644
58645
58646
58647





58648
58649
58650
58651
58652
58653
58654
58655
58656


58657
58658

58659

58660

58661


58662
58663
58664
58665












58666
58667




58668





58669





58670


58671
58672







58673


58674



58675
58676


58677



58678

58679










58680
58681
58682
58683
58684
58685
58686
58687
58688
58689
58690
58691
58692
58693
58694
58695
58696
58697
58698
58699
58700
58701
58702
58703
58704
58705
58706
58707
58708
58709
58710
58711
58712
58713
58714
58715
58716
58717
58718
58719
58720
58721
58722
58723
58724
58725
58726
58727
58728
58729
58730
58731
58732
58733
58734
































58735



58736



58737








58738











58739
58740
58741
58742
58743
58744
58745
58746
58747
58748
58749
58750
58751
58752
58753
58754
58755
58756
58757
58758
58759


58760
58761


58762
58763

58764
58765
58766
58767
58768
58769
58770
58771
58772
58773
58774
58775
58776
58777
58778
58779
58780
58781
58782
58783
58784
58785
58786
58787
58788
58789
58790
58791
58792
58793
58794
58795
58796
58797
58798
58799
58800
58801
58802
58803
58804
58805
58806
58807
58808
58809
58810
58811
58812
58813
58814
58815
58816
58817
58818
58819
58820
58821
58822
58823
58824
58825
58826
58827
58828
58829
58830
58831
58832
58833
58834
58835
58836
58837
58838
58839
58840
58841
58842
58843
58844
58845
58846
58847
58848
58849
58850
58851
58852
58853
58854
58855
58856
58857
58858
58859
58860
58861
58862










58863
58864

58865
58866
58867
58868
58869
58870
58871
58872
58873
58874
58875
58876
58877
58878
58879
58880
58881
58882
58883
      rc = sqlite3PagerWrite(pNew->pDbPage);
      nNew++;
      if( rc ) goto balance_cleanup;
    }else{
      assert( i>0 );
      rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
      if( rc ) goto balance_cleanup;

      apNew[i] = pNew;
      nNew++;


      /* Set the pointer-map entry for the new sibling page. */
      if( ISAUTOVACUUM ){
        ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
        if( rc!=SQLITE_OK ){
          goto balance_cleanup;
        }
      }
    }
  }

  /* Free any old pages that were not reused as new pages.
  */
  while( i<nOld ){
    freePage(apOld[i], &rc);
    if( rc ) goto balance_cleanup;
    releasePage(apOld[i]);
    apOld[i] = 0;
    i++;
  }

  /*
  ** Put the new pages in ascending order.  This helps to
  ** keep entries in the disk file in order so that a scan
  ** of the table is a linear scan through the file.  That
  ** in turn helps the operating system to deliver pages
  ** from the disk more rapidly.
  **
  ** An O(n^2) insertion sort algorithm is used, but since
  ** n is never more than NB (a small constant), that should
  ** not be a problem.
  **
  ** When NB==3, this one optimization makes the database
  ** about 25% faster for large insertions and deletions.
  */
  for(i=0; i<k-1; i++){

    int minV = apNew[i]->pgno;









    int minI = i;




    for(j=i+1; j<k; j++){

      if( apNew[j]->pgno<(unsigned)minV ){
        minI = j;
        minV = apNew[j]->pgno;
      }





    }
    if( minI>i ){
      MemPage *pT;
      pT = apNew[i];
      apNew[i] = apNew[minI];
      apNew[minI] = pT;
    }
  }
  TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",


    apNew[0]->pgno, szNew[0],
    nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,

    nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0,

    nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0,

    nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0));



  assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  put4byte(pRight, apNew[nNew-1]->pgno);













  /*
  ** Evenly distribute the data in apCell[] across the new pages.




  ** Insert divider cells into pParent as necessary.





  */





  j = 0;


  for(i=0; i<nNew; i++){
    /* Assemble the new sibling page. */







    MemPage *pNew = apNew[i];


    assert( j<nMaxCells );



    zeroPage(pNew, pageFlags);
    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);


    assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );



    assert( pNew->nOverflow==0 );












    j = cntNew[i];

    /* If the sibling page assembled above was not the right-most sibling,
    ** insert a divider cell into the parent page.
    */
    assert( i<nNew-1 || j==nCell );
    if( j<nCell ){
      u8 *pCell;
      u8 *pTemp;
      int sz;

      assert( j<nMaxCells );
      pCell = apCell[j];
      sz = szCell[j] + leafCorrection;
      pTemp = &aOvflSpace[iOvflSpace];
      if( !pNew->leaf ){
        memcpy(&pNew->aData[8], pCell, 4);
      }else if( leafData ){
        /* If the tree is a leaf-data tree, and the siblings are leaves, 
        ** then there is no divider cell in apCell[]. Instead, the divider 
        ** cell consists of the integer key for the right-most cell of 
        ** the sibling-page assembled above only.
        */
        CellInfo info;
        j--;
        btreeParseCellPtr(pNew, apCell[j], &info);
        pCell = pTemp;
        sz = 4 + putVarint(&pCell[4], info.nKey);
        pTemp = 0;
      }else{
        pCell -= 4;
        /* Obscure case for non-leaf-data trees: If the cell at pCell was
        ** previously stored on a leaf node, and its reported size was 4
        ** bytes, then it may actually be smaller than this 
        ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
        ** any cell). But it is important to pass the correct size to 
        ** insertCell(), so reparse the cell now.
        **
        ** Note that this can never happen in an SQLite data file, as all
        ** cells are at least 4 bytes. It only happens in b-trees used
        ** to evaluate "IN (SELECT ...)" and similar clauses.
        */
        if( szCell[j]==4 ){
          assert(leafCorrection==4);
          sz = cellSizePtr(pParent, pCell);
        }
      }
      iOvflSpace += sz;
      assert( sz<=pBt->maxLocal+23 );
      assert( iOvflSpace <= (int)pBt->pageSize );
      insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
      if( rc!=SQLITE_OK ) goto balance_cleanup;
      assert( sqlite3PagerIswriteable(pParent->pDbPage) );

      j++;
































      nxDiv++;



    }



  }








  assert( j==nCell );











  assert( nOld>0 );
  assert( nNew>0 );
  if( (pageFlags & PTF_LEAF)==0 ){
    u8 *zChild = &apCopy[nOld-1]->aData[8];
    memcpy(&apNew[nNew-1]->aData[8], zChild, 4);
  }

  if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){
    /* The root page of the b-tree now contains no cells. The only sibling
    ** page is the right-child of the parent. Copy the contents of the
    ** child page into the parent, decreasing the overall height of the
    ** b-tree structure by one. This is described as the "balance-shallower"
    ** sub-algorithm in some documentation.
    **
    ** If this is an auto-vacuum database, the call to copyNodeContent() 
    ** sets all pointer-map entries corresponding to database image pages 
    ** for which the pointer is stored within the content being copied.
    **
    ** The second assert below verifies that the child page is defragmented
    ** (it must be, as it was just reconstructed using assemblePage()). This
    ** is important if the parent page happens to be page 1 of the database


    ** image.  */
    assert( nNew==1 );


    assert( apNew[0]->nFree == 
        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) 

    );
    copyNodeContent(apNew[0], pParent, &rc);
    freePage(apNew[0], &rc);
  }else if( ISAUTOVACUUM ){
    /* Fix the pointer-map entries for all the cells that were shifted around. 
    ** There are several different types of pointer-map entries that need to
    ** be dealt with by this routine. Some of these have been set already, but
    ** many have not. The following is a summary:
    **
    **   1) The entries associated with new sibling pages that were not
    **      siblings when this function was called. These have already
    **      been set. We don't need to worry about old siblings that were
    **      moved to the free-list - the freePage() code has taken care
    **      of those.
    **
    **   2) The pointer-map entries associated with the first overflow
    **      page in any overflow chains used by new divider cells. These 
    **      have also already been taken care of by the insertCell() code.
    **
    **   3) If the sibling pages are not leaves, then the child pages of
    **      cells stored on the sibling pages may need to be updated.
    **
    **   4) If the sibling pages are not internal intkey nodes, then any
    **      overflow pages used by these cells may need to be updated
    **      (internal intkey nodes never contain pointers to overflow pages).
    **
    **   5) If the sibling pages are not leaves, then the pointer-map
    **      entries for the right-child pages of each sibling may need
    **      to be updated.
    **
    ** Cases 1 and 2 are dealt with above by other code. The next
    ** block deals with cases 3 and 4 and the one after that, case 5. Since
    ** setting a pointer map entry is a relatively expensive operation, this
    ** code only sets pointer map entries for child or overflow pages that have
    ** actually moved between pages.  */
    MemPage *pNew = apNew[0];
    MemPage *pOld = apCopy[0];
    int nOverflow = pOld->nOverflow;
    int iNextOld = pOld->nCell + nOverflow;
    int iOverflow = (nOverflow ? pOld->aiOvfl[0] : -1);
    j = 0;                             /* Current 'old' sibling page */
    k = 0;                             /* Current 'new' sibling page */
    for(i=0; i<nCell; i++){
      int isDivider = 0;
      while( i==iNextOld ){
        /* Cell i is the cell immediately following the last cell on old
        ** sibling page j. If the siblings are not leaf pages of an
        ** intkey b-tree, then cell i was a divider cell. */
        assert( j+1 < ArraySize(apCopy) );
        assert( j+1 < nOld );
        pOld = apCopy[++j];
        iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
        if( pOld->nOverflow ){
          nOverflow = pOld->nOverflow;
          iOverflow = i + !leafData + pOld->aiOvfl[0];
        }
        isDivider = !leafData;  
      }

      assert(nOverflow>0 || iOverflow<i );
      assert(nOverflow<2 || pOld->aiOvfl[0]==pOld->aiOvfl[1]-1);
      assert(nOverflow<3 || pOld->aiOvfl[1]==pOld->aiOvfl[2]-1);
      if( i==iOverflow ){
        isDivider = 1;
        if( (--nOverflow)>0 ){
          iOverflow++;
        }
      }

      if( i==cntNew[k] ){
        /* Cell i is the cell immediately following the last cell on new
        ** sibling page k. If the siblings are not leaf pages of an
        ** intkey b-tree, then cell i is a divider cell.  */
        pNew = apNew[++k];
        if( !leafData ) continue;
      }
      assert( j<nOld );
      assert( k<nNew );

      /* If the cell was originally divider cell (and is not now) or
      ** an overflow cell, or if the cell was located on a different sibling
      ** page before the balancing, then the pointer map entries associated
      ** with any child or overflow pages need to be updated.  */
      if( isDivider || pOld->pgno!=pNew->pgno ){
        if( !leafCorrection ){
          ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc);
        }
        if( szCell[i]>pNew->minLocal ){
          ptrmapPutOvflPtr(pNew, apCell[i], &rc);
        }
      }
    }

    if( !leafCorrection ){
      for(i=0; i<nNew; i++){
        u32 key = get4byte(&apNew[i]->aData[8]);
        ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
      }
    }











#if 0

    /* The ptrmapCheckPages() contains assert() statements that verify that
    ** all pointer map pages are set correctly. This is helpful while 
    ** debugging. This is usually disabled because a corrupt database may
    ** cause an assert() statement to fail.  */
    ptrmapCheckPages(apNew, nNew);
    ptrmapCheckPages(&pParent, 1);
#endif
  }

  assert( pParent->isInit );
  TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
          nOld, nNew, nCell));

  /*
  ** Cleanup before returning.
  */
balance_cleanup:
  sqlite3ScratchFree(apCell);
  for(i=0; i<nOld; i++){







>


>











<
<
<
<
<
<
<
<
<
<

|
|
|
|
<

|
|
<

|
|

|
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
|
|
<
|
>
>
>
>
>
|
<
|
|
<
<


|
>
>
|

>

>

>
|
>
>




>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
|
>
>
>
>
>

>
>
>
>
>
|
>
>
|
<
>
>
>
>
>
>
>
|
>
>
|
>
>
>
|
<
>
>
|
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>


<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>


<
<
<
<












|
<
|
>
>
|

>
>

|
>



|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>


>






<

|
<
<
<







59431
59432
59433
59434
59435
59436
59437
59438
59439
59440
59441
59442
59443
59444
59445
59446
59447
59448
59449
59450
59451
59452










59453
59454
59455
59456
59457

59458
59459
59460

59461
59462
59463
59464
59465
59466
59467
59468
59469
59470
59471
59472
59473
59474
59475
59476
59477
59478
59479
59480
59481
59482
59483
59484
59485

59486
59487
59488
59489
59490
59491
59492

59493
59494


59495
59496
59497
59498
59499
59500
59501
59502
59503
59504
59505
59506
59507
59508
59509
59510
59511
59512
59513
59514
59515
59516
59517
59518
59519
59520
59521
59522
59523
59524
59525
59526

59527
59528
59529
59530
59531
59532
59533
59534
59535
59536
59537
59538
59539
59540
59541
59542
59543
59544
59545
59546

59547
59548
59549
59550
59551
59552
59553
59554
59555
59556
59557
59558
59559
59560
59561

59562
59563
59564
59565
59566
59567
59568
59569
59570
59571
59572
59573
59574
59575
59576
59577
59578
59579
59580
59581
59582









59583
59584
59585
59586
59587
59588
59589
59590
59591
59592
59593
59594
59595
59596
59597
59598
59599
59600
59601
59602
59603
59604
59605
59606
59607
59608
59609
59610
59611
59612
59613
59614
59615
59616
59617
59618
59619
59620
59621
59622
59623
59624
59625
59626
59627
59628
59629
59630
59631
59632
59633
59634
59635
59636
59637
59638
59639
59640
59641
59642
59643
59644
59645
59646
59647
59648
59649
59650
59651
59652
59653
59654
59655
59656
59657
59658
59659
59660
59661
59662
59663
59664
59665
59666
59667
59668
59669
59670
59671
59672
59673
59674
59675
59676
59677
59678
59679
59680
59681
59682
59683
59684
59685
59686
59687
59688
59689




59690
59691
59692
59693
59694
59695
59696
59697
59698
59699
59700
59701
59702

59703
59704
59705
59706
59707
59708
59709
59710
59711
59712
59713
59714
59715
59716











59717










































59718









59719

























59720
59721
59722
59723
59724
59725
59726
59727
59728
59729
59730
59731
59732
59733
59734
59735
59736
59737
59738
59739
59740
59741
59742
59743

59744
59745



59746
59747
59748
59749
59750
59751
59752
      rc = sqlite3PagerWrite(pNew->pDbPage);
      nNew++;
      if( rc ) goto balance_cleanup;
    }else{
      assert( i>0 );
      rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
      if( rc ) goto balance_cleanup;
      zeroPage(pNew, pageFlags);
      apNew[i] = pNew;
      nNew++;
      cntOld[i] = nCell;

      /* Set the pointer-map entry for the new sibling page. */
      if( ISAUTOVACUUM ){
        ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
        if( rc!=SQLITE_OK ){
          goto balance_cleanup;
        }
      }
    }
  }











  /*
  ** Reassign page numbers so that the new pages are in ascending order. 
  ** This helps to keep entries in the disk file in order so that a scan
  ** of the table is closer to a linear scan through the file. That in turn 
  ** helps the operating system to deliver pages from the disk more rapidly.

  **
  ** An O(n^2) insertion sort algorithm is used, but since n is never more 
  ** than (NB+2) (a small constant), that should not be a problem.

  **
  ** When NB==3, this one optimization makes the database about 25% faster 
  ** for large insertions and deletions.
  */
  for(i=0; i<nNew; i++){
    aPgOrder[i] = aPgno[i] = apNew[i]->pgno;
    aPgFlags[i] = apNew[i]->pDbPage->flags;
    for(j=0; j<i; j++){
      if( aPgno[j]==aPgno[i] ){
        /* This branch is taken if the set of sibling pages somehow contains
        ** duplicate entries. This can happen if the database is corrupt. 
        ** It would be simpler to detect this as part of the loop below, but
        ** we do the detection here in order to avoid populating the pager
        ** cache with two separate objects associated with the same
        ** page number.  */
        assert( CORRUPT_DB );
        rc = SQLITE_CORRUPT_BKPT;
        goto balance_cleanup;
      }
    }
  }
  for(i=0; i<nNew; i++){
    int iBest = 0;                /* aPgno[] index of page number to use */
    for(j=1; j<nNew; j++){
      if( aPgOrder[j]<aPgOrder[iBest] ) iBest = j;

    }
    pgno = aPgOrder[iBest];
    aPgOrder[iBest] = 0xffffffff;
    if( iBest!=i ){
      if( iBest>i ){
        sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
      }

      sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]);
      apNew[i]->pgno = pgno;


    }
  }

  TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) "
         "%d(%d nc=%d) %d(%d nc=%d)\n",
    apNew[0]->pgno, szNew[0], cntNew[0],
    nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,
    nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0,
    nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0,
    nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0,
    nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0,
    nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0,
    nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0,
    nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0
  ));

  assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  put4byte(pRight, apNew[nNew-1]->pgno);

  /* If the sibling pages are not leaves, ensure that the right-child pointer
  ** of the right-most new sibling page is set to the value that was 
  ** originally in the same field of the right-most old sibling page. */
  if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){
    MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1];
    memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4);
  }

  /* Make any required updates to pointer map entries associated with 
  ** cells stored on sibling pages following the balance operation. Pointer
  ** map entries associated with divider cells are set by the insertCell()
  ** routine. The associated pointer map entries are:
  **

  **   a) if the cell contains a reference to an overflow chain, the
  **      entry associated with the first page in the overflow chain, and
  **
  **   b) if the sibling pages are not leaves, the child page associated
  **      with the cell.
  **
  ** If the sibling pages are not leaves, then the pointer map entry 
  ** associated with the right-child of each sibling may also need to be 
  ** updated. This happens below, after the sibling pages have been 
  ** populated, not here.
  */
  if( ISAUTOVACUUM ){
    MemPage *pNew = apNew[0];
    u8 *aOld = pNew->aData;
    int cntOldNext = pNew->nCell + pNew->nOverflow;
    int usableSize = pBt->usableSize;
    int iNew = 0;
    int iOld = 0;

    for(i=0; i<nCell; i++){

      u8 *pCell = apCell[i];
      if( i==cntOldNext ){
        MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
        cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
        aOld = pOld->aData;
      }
      if( i==cntNew[iNew] ){
        pNew = apNew[++iNew];
        if( !leafData ) continue;
      }

      /* Cell pCell is destined for new sibling page pNew. Originally, it
      ** was either part of sibling page iOld (possibly an overflow cell), 
      ** or else the divider cell to the left of sibling page iOld. So,
      ** if sibling page iOld had the same page number as pNew, and if

      ** pCell really was a part of sibling page iOld (not a divider or
      ** overflow cell), we can skip updating the pointer map entries.  */
      if( pNew->pgno!=aPgno[iOld] || pCell<aOld || pCell>=&aOld[usableSize] ){
        if( !leafCorrection ){
          ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
        }
        if( szCell[i]>pNew->minLocal ){
          ptrmapPutOvflPtr(pNew, pCell, &rc);
        }
      }
    }
  }

  /* Insert new divider cells into pParent. */
  for(i=0; i<nNew-1; i++){
    u8 *pCell;
    u8 *pTemp;
    int sz;
    MemPage *pNew = apNew[i];
    j = cntNew[i];










    assert( j<nMaxCells );
    pCell = apCell[j];
    sz = szCell[j] + leafCorrection;
    pTemp = &aOvflSpace[iOvflSpace];
    if( !pNew->leaf ){
      memcpy(&pNew->aData[8], pCell, 4);
    }else if( leafData ){
      /* If the tree is a leaf-data tree, and the siblings are leaves, 
      ** then there is no divider cell in apCell[]. Instead, the divider 
      ** cell consists of the integer key for the right-most cell of 
      ** the sibling-page assembled above only.
      */
      CellInfo info;
      j--;
      btreeParseCellPtr(pNew, apCell[j], &info);
      pCell = pTemp;
      sz = 4 + putVarint(&pCell[4], info.nKey);
      pTemp = 0;
    }else{
      pCell -= 4;
      /* Obscure case for non-leaf-data trees: If the cell at pCell was
      ** previously stored on a leaf node, and its reported size was 4
      ** bytes, then it may actually be smaller than this 
      ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
      ** any cell). But it is important to pass the correct size to 
      ** insertCell(), so reparse the cell now.
      **
      ** Note that this can never happen in an SQLite data file, as all
      ** cells are at least 4 bytes. It only happens in b-trees used
      ** to evaluate "IN (SELECT ...)" and similar clauses.
      */
      if( szCell[j]==4 ){
        assert(leafCorrection==4);
        sz = cellSizePtr(pParent, pCell);
      }
    }
    iOvflSpace += sz;
    assert( sz<=pBt->maxLocal+23 );
    assert( iOvflSpace <= (int)pBt->pageSize );
    insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc);
    if( rc!=SQLITE_OK ) goto balance_cleanup;
    assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  }

  /* Now update the actual sibling pages. The order in which they are updated
  ** is important, as this code needs to avoid disrupting any page from which
  ** cells may still to be read. In practice, this means:
  **
  **  (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1])
  **      then it is not safe to update page apNew[iPg] until after
  **      the left-hand sibling apNew[iPg-1] has been updated.
  **
  **  (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1])
  **      then it is not safe to update page apNew[iPg] until after
  **      the right-hand sibling apNew[iPg+1] has been updated.
  **
  ** If neither of the above apply, the page is safe to update.
  **
  ** The iPg value in the following loop starts at nNew-1 goes down
  ** to 0, then back up to nNew-1 again, thus making two passes over
  ** the pages.  On the initial downward pass, only condition (1) above
  ** needs to be tested because (2) will always be true from the previous
  ** step.  On the upward pass, both conditions are always true, so the
  ** upwards pass simply processes pages that were missed on the downward
  ** pass.
  */
  for(i=1-nNew; i<nNew; i++){
    int iPg = i<0 ? -i : i;
    assert( iPg>=0 && iPg<nNew );
    if( abDone[iPg] ) continue;         /* Skip pages already processed */
    if( i>=0                            /* On the upwards pass, or... */
     || cntOld[iPg-1]>=cntNew[iPg-1]    /* Condition (1) is true */
    ){
      int iNew;
      int iOld;
      int nNewCell;

      /* Verify condition (1):  If cells are moving left, update iPg
      ** only after iPg-1 has already been updated. */
      assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] );

      /* Verify condition (2):  If cells are moving right, update iPg
      ** only after iPg+1 has already been updated. */
      assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] );

      if( iPg==0 ){
        iNew = iOld = 0;
        nNewCell = cntNew[0];
      }else{
        iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : nCell;
        iNew = cntNew[iPg-1] + !leafData;
        nNewCell = cntNew[iPg] - iNew;
      }

      editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
      abDone[iPg]++;
      apNew[iPg]->nFree = usableSpace-szNew[iPg];
      assert( apNew[iPg]->nOverflow==0 );
      assert( apNew[iPg]->nCell==nNewCell );
    }
  }

  /* All pages have been processed exactly once */
  assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 );

  assert( nOld>0 );
  assert( nNew>0 );





  if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){
    /* The root page of the b-tree now contains no cells. The only sibling
    ** page is the right-child of the parent. Copy the contents of the
    ** child page into the parent, decreasing the overall height of the
    ** b-tree structure by one. This is described as the "balance-shallower"
    ** sub-algorithm in some documentation.
    **
    ** If this is an auto-vacuum database, the call to copyNodeContent() 
    ** sets all pointer-map entries corresponding to database image pages 
    ** for which the pointer is stored within the content being copied.
    **
    ** It is critical that the child page be defragmented before being

    ** copied into the parent, because if the parent is page 1 then it will
    ** by smaller than the child due to the database header, and so all the
    ** free space needs to be up front.
    */
    assert( nNew==1 );
    rc = defragmentPage(apNew[0]);
    testcase( rc!=SQLITE_OK );
    assert( apNew[0]->nFree == 
        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
      || rc!=SQLITE_OK
    );
    copyNodeContent(apNew[0], pParent, &rc);
    freePage(apNew[0], &rc);
  }else if( ISAUTOVACUUM && !leafCorrection ){











    /* Fix the pointer map entries associated with the right-child of each










































    ** sibling page. All other pointer map entries have already been taken









    ** care of.  */

























    for(i=0; i<nNew; i++){
      u32 key = get4byte(&apNew[i]->aData[8]);
      ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
    }
  }

  assert( pParent->isInit );
  TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
          nOld, nNew, nCell));

  /* Free any old pages that were not reused as new pages.
  */
  for(i=nNew; i<nOld; i++){
    freePage(apOld[i], &rc);
  }

#if 0
  if( ISAUTOVACUUM && rc==SQLITE_OK && apNew[0]->isInit ){
    /* The ptrmapCheckPages() contains assert() statements that verify that
    ** all pointer map pages are set correctly. This is helpful while 
    ** debugging. This is usually disabled because a corrupt database may
    ** cause an assert() statement to fail.  */
    ptrmapCheckPages(apNew, nNew);
    ptrmapCheckPages(&pParent, 1);

  }
#endif




  /*
  ** Cleanup before returning.
  */
balance_cleanup:
  sqlite3ScratchFree(apCell);
  for(i=0; i<nOld; i++){
59006
59007
59008
59009
59010
59011
59012
59013
59014
59015
59016
59017
59018
59019
59020
    }else{
      MemPage * const pParent = pCur->apPage[iPage-1];
      int const iIdx = pCur->aiIdx[iPage-1];

      rc = sqlite3PagerWrite(pParent->pDbPage);
      if( rc==SQLITE_OK ){
#ifndef SQLITE_OMIT_QUICKBALANCE
        if( pPage->hasData
         && pPage->nOverflow==1
         && pPage->aiOvfl[0]==pPage->nCell
         && pParent->pgno!=1
         && pParent->nCell==iIdx
        ){
          /* Call balance_quick() to create a new sibling of pPage on which
          ** to store the overflow cell. balance_quick() inserts a new cell







|







59875
59876
59877
59878
59879
59880
59881
59882
59883
59884
59885
59886
59887
59888
59889
    }else{
      MemPage * const pParent = pCur->apPage[iPage-1];
      int const iIdx = pCur->aiIdx[iPage-1];

      rc = sqlite3PagerWrite(pParent->pDbPage);
      if( rc==SQLITE_OK ){
#ifndef SQLITE_OMIT_QUICKBALANCE
        if( pPage->intKeyLeaf
         && pPage->nOverflow==1
         && pPage->aiOvfl[0]==pPage->nCell
         && pParent->pgno!=1
         && pParent->nCell==iIdx
        ){
          /* Call balance_quick() to create a new sibling of pPage on which
          ** to store the overflow cell. balance_quick() inserts a new cell
59125
59126
59127
59128
59129
59130
59131
59132

59133
59134
59135
59136
59137
59138
59139

  if( pCur->eState==CURSOR_FAULT ){
    assert( pCur->skipNext!=SQLITE_OK );
    return pCur->skipNext;
  }

  assert( cursorHoldsMutex(pCur) );
  assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE

              && (pBt->btsFlags & BTS_READ_ONLY)==0 );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );

  /* Assert that the caller has been consistent. If this cursor was opened
  ** expecting an index b-tree, then the caller should be inserting blob
  ** keys with no associated data. If the cursor was opened expecting an
  ** intkey table, the caller should be inserting integer keys with a







|
>







59994
59995
59996
59997
59998
59999
60000
60001
60002
60003
60004
60005
60006
60007
60008
60009

  if( pCur->eState==CURSOR_FAULT ){
    assert( pCur->skipNext!=SQLITE_OK );
    return pCur->skipNext;
  }

  assert( cursorHoldsMutex(pCur) );
  assert( (pCur->curFlags & BTCF_WriteFlag)!=0
              && pBt->inTransaction==TRANS_WRITE
              && (pBt->btsFlags & BTS_READ_ONLY)==0 );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );

  /* Assert that the caller has been consistent. If this cursor was opened
  ** expecting an index b-tree, then the caller should be inserting blob
  ** keys with no associated data. If the cursor was opened expecting an
  ** intkey table, the caller should be inserting integer keys with a
59158
59159
59160
59161
59162
59163
59164
59165

59166
59167
59168
59169
59170
59171
59172
59173
59174
59175
59176
59177
59178
59179
59180
59181
59182
59183
59184
59185
59186
59187
59188
59189
59190
59191
59192
59193
59194
59195
59196
59197
59198
59199
59200
59201
59202
59203
59204
59205
59206
59207
59208
59209
59210
59211
    /* If this is an insert into a table b-tree, invalidate any incrblob 
    ** cursors open on the row being replaced */
    invalidateIncrblobCursors(p, nKey, 0);

    /* If the cursor is currently on the last row and we are appending a
    ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
    ** call */
    if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){

      loc = -1;
    }
  }

  if( !loc ){
    rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
    if( rc ) return rc;
  }
  assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );

  pPage = pCur->apPage[pCur->iPage];
  assert( pPage->intKey || nKey>=0 );
  assert( pPage->leaf || !pPage->intKey );

  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );
  allocateTempSpace(pBt);
  newCell = pBt->pTmpSpace;
  if( newCell==0 ) return SQLITE_NOMEM;
  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
  if( rc ) goto end_insert;
  assert( szNew==cellSizePtr(pPage, newCell) );
  assert( szNew <= MX_CELL_SIZE(pBt) );
  idx = pCur->aiIdx[pCur->iPage];
  if( loc==0 ){
    u16 szOld;
    assert( idx<pPage->nCell );
    rc = sqlite3PagerWrite(pPage->pDbPage);
    if( rc ){
      goto end_insert;
    }
    oldCell = findCell(pPage, idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }
    szOld = cellSizePtr(pPage, oldCell);
    rc = clearCell(pPage, oldCell);
    dropCell(pPage, idx, szOld, &rc);
    if( rc ) goto end_insert;
  }else if( loc<0 && pPage->nCell>0 ){
    assert( pPage->leaf );
    idx = ++pCur->aiIdx[pCur->iPage];
  }else{
    assert( pPage->leaf );







|
>


















<

|
















<
|







60028
60029
60030
60031
60032
60033
60034
60035
60036
60037
60038
60039
60040
60041
60042
60043
60044
60045
60046
60047
60048
60049
60050
60051
60052
60053
60054

60055
60056
60057
60058
60059
60060
60061
60062
60063
60064
60065
60066
60067
60068
60069
60070
60071
60072

60073
60074
60075
60076
60077
60078
60079
60080
    /* If this is an insert into a table b-tree, invalidate any incrblob 
    ** cursors open on the row being replaced */
    invalidateIncrblobCursors(p, nKey, 0);

    /* If the cursor is currently on the last row and we are appending a
    ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
    ** call */
    if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0
      && pCur->info.nKey==nKey-1 ){
      loc = -1;
    }
  }

  if( !loc ){
    rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
    if( rc ) return rc;
  }
  assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );

  pPage = pCur->apPage[pCur->iPage];
  assert( pPage->intKey || nKey>=0 );
  assert( pPage->leaf || !pPage->intKey );

  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );

  newCell = pBt->pTmpSpace;
  assert( newCell!=0 );
  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
  if( rc ) goto end_insert;
  assert( szNew==cellSizePtr(pPage, newCell) );
  assert( szNew <= MX_CELL_SIZE(pBt) );
  idx = pCur->aiIdx[pCur->iPage];
  if( loc==0 ){
    u16 szOld;
    assert( idx<pPage->nCell );
    rc = sqlite3PagerWrite(pPage->pDbPage);
    if( rc ){
      goto end_insert;
    }
    oldCell = findCell(pPage, idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }

    rc = clearCell(pPage, oldCell, &szOld);
    dropCell(pPage, idx, szOld, &rc);
    if( rc ) goto end_insert;
  }else if( loc<0 && pPage->nCell>0 ){
    assert( pPage->leaf );
    idx = ++pCur->aiIdx[pCur->iPage];
  }else{
    assert( pPage->leaf );
59259
59260
59261
59262
59263
59264
59265

59266
59267
59268
59269
59270
59271
59272
  Btree *p = pCur->pBtree;
  BtShared *pBt = p->pBt;              
  int rc;                              /* Return code */
  MemPage *pPage;                      /* Page to delete cell from */
  unsigned char *pCell;                /* Pointer to cell to delete */
  int iCellIdx;                        /* Index of cell to delete */
  int iCellDepth;                      /* Depth of node containing pCell */ 


  assert( cursorHoldsMutex(pCur) );
  assert( pBt->inTransaction==TRANS_WRITE );
  assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  assert( pCur->curFlags & BTCF_WriteFlag );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  assert( !hasReadConflicts(p, pCur->pgnoRoot) );







>







60128
60129
60130
60131
60132
60133
60134
60135
60136
60137
60138
60139
60140
60141
60142
  Btree *p = pCur->pBtree;
  BtShared *pBt = p->pBt;              
  int rc;                              /* Return code */
  MemPage *pPage;                      /* Page to delete cell from */
  unsigned char *pCell;                /* Pointer to cell to delete */
  int iCellIdx;                        /* Index of cell to delete */
  int iCellDepth;                      /* Depth of node containing pCell */ 
  u16 szCell;                          /* Size of the cell being deleted */

  assert( cursorHoldsMutex(pCur) );
  assert( pBt->inTransaction==TRANS_WRITE );
  assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  assert( pCur->curFlags & BTCF_WriteFlag );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  assert( !hasReadConflicts(p, pCur->pgnoRoot) );
59307
59308
59309
59310
59311
59312
59313
59314
59315
59316
59317
59318
59319
59320
59321
59322
59323
59324
59325
59326
59327
59328
59329
59330
59331
59332
59333
59334
59335
59336
59337
59338
59339
59340
59341
59342
  ** invalidate any incrblob cursors open on the row being deleted.  */
  if( pCur->pKeyInfo==0 ){
    invalidateIncrblobCursors(p, pCur->info.nKey, 0);
  }

  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc ) return rc;
  rc = clearCell(pPage, pCell);
  dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
  if( rc ) return rc;

  /* If the cell deleted was not located on a leaf page, then the cursor
  ** is currently pointing to the largest entry in the sub-tree headed
  ** by the child-page of the cell that was just deleted from an internal
  ** node. The cell from the leaf node needs to be moved to the internal
  ** node to replace the deleted cell.  */
  if( !pPage->leaf ){
    MemPage *pLeaf = pCur->apPage[pCur->iPage];
    int nCell;
    Pgno n = pCur->apPage[iCellDepth+1]->pgno;
    unsigned char *pTmp;

    pCell = findCell(pLeaf, pLeaf->nCell-1);
    nCell = cellSizePtr(pLeaf, pCell);
    assert( MX_CELL_SIZE(pBt) >= nCell );

    allocateTempSpace(pBt);
    pTmp = pBt->pTmpSpace;

    rc = sqlite3PagerWrite(pLeaf->pDbPage);
    insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
    if( rc ) return rc;
  }

  /* Balance the tree. If the entry deleted was located on a leaf page,







|
|
















<
<

|







60177
60178
60179
60180
60181
60182
60183
60184
60185
60186
60187
60188
60189
60190
60191
60192
60193
60194
60195
60196
60197
60198
60199
60200
60201


60202
60203
60204
60205
60206
60207
60208
60209
60210
  ** invalidate any incrblob cursors open on the row being deleted.  */
  if( pCur->pKeyInfo==0 ){
    invalidateIncrblobCursors(p, pCur->info.nKey, 0);
  }

  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc ) return rc;
  rc = clearCell(pPage, pCell, &szCell);
  dropCell(pPage, iCellIdx, szCell, &rc);
  if( rc ) return rc;

  /* If the cell deleted was not located on a leaf page, then the cursor
  ** is currently pointing to the largest entry in the sub-tree headed
  ** by the child-page of the cell that was just deleted from an internal
  ** node. The cell from the leaf node needs to be moved to the internal
  ** node to replace the deleted cell.  */
  if( !pPage->leaf ){
    MemPage *pLeaf = pCur->apPage[pCur->iPage];
    int nCell;
    Pgno n = pCur->apPage[iCellDepth+1]->pgno;
    unsigned char *pTmp;

    pCell = findCell(pLeaf, pLeaf->nCell-1);
    nCell = cellSizePtr(pLeaf, pCell);
    assert( MX_CELL_SIZE(pBt) >= nCell );


    pTmp = pBt->pTmpSpace;
    assert( pTmp!=0 );
    rc = sqlite3PagerWrite(pLeaf->pDbPage);
    insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
    if( rc ) return rc;
  }

  /* Balance the tree. If the entry deleted was located on a leaf page,
59540
59541
59542
59543
59544
59545
59546

59547
59548
59549
59550
59551
59552
59553
59554
59555
59556
59557
59558
59559
59560
59561
59562
59563
59564
59565
59566
59567
59568
59569
  int *pnChange            /* Add number of Cells freed to this counter */
){
  MemPage *pPage;
  int rc;
  unsigned char *pCell;
  int i;
  int hdr;


  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pgno>btreePagecount(pBt) ){
    return SQLITE_CORRUPT_BKPT;
  }

  rc = getAndInitPage(pBt, pgno, &pPage, 0);
  if( rc ) return rc;
  hdr = pPage->hdrOffset;
  for(i=0; i<pPage->nCell; i++){
    pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
      if( rc ) goto cleardatabasepage_out;
    }
    rc = clearCell(pPage, pCell);
    if( rc ) goto cleardatabasepage_out;
  }
  if( !pPage->leaf ){
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
    if( rc ) goto cleardatabasepage_out;
  }else if( pnChange ){
    assert( pPage->intKey );







>















|







60408
60409
60410
60411
60412
60413
60414
60415
60416
60417
60418
60419
60420
60421
60422
60423
60424
60425
60426
60427
60428
60429
60430
60431
60432
60433
60434
60435
60436
60437
60438
  int *pnChange            /* Add number of Cells freed to this counter */
){
  MemPage *pPage;
  int rc;
  unsigned char *pCell;
  int i;
  int hdr;
  u16 szCell;

  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pgno>btreePagecount(pBt) ){
    return SQLITE_CORRUPT_BKPT;
  }

  rc = getAndInitPage(pBt, pgno, &pPage, 0);
  if( rc ) return rc;
  hdr = pPage->hdrOffset;
  for(i=0; i<pPage->nCell; i++){
    pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
      if( rc ) goto cleardatabasepage_out;
    }
    rc = clearCell(pPage, pCell, &szCell);
    if( rc ) goto cleardatabasepage_out;
  }
  if( !pPage->leaf ){
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
    if( rc ) goto cleardatabasepage_out;
  }else if( pnChange ){
    assert( pPage->intKey );
59901
59902
59903
59904
59905
59906
59907
59908
59909
59910
59911
59912

59913
59914
59915
59916
59917
59918
59919
59920

59921
59922
59923
59924
59925
59926
59927
59928

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Append a message to the error message string.
*/
static void checkAppendMsg(
  IntegrityCk *pCheck,
  char *zMsg1,
  const char *zFormat,
  ...
){
  va_list ap;

  if( !pCheck->mxErr ) return;
  pCheck->mxErr--;
  pCheck->nErr++;
  va_start(ap, zFormat);
  if( pCheck->errMsg.nChar ){
    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
  }
  if( zMsg1 ){

    sqlite3StrAccumAppendAll(&pCheck->errMsg, zMsg1);
  }
  sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
  va_end(ap);
  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
    pCheck->mallocFailed = 1;
  }
}







<




>







|
>
|







60770
60771
60772
60773
60774
60775
60776

60777
60778
60779
60780
60781
60782
60783
60784
60785
60786
60787
60788
60789
60790
60791
60792
60793
60794
60795
60796
60797
60798

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Append a message to the error message string.
*/
static void checkAppendMsg(
  IntegrityCk *pCheck,

  const char *zFormat,
  ...
){
  va_list ap;
  char zBuf[200];
  if( !pCheck->mxErr ) return;
  pCheck->mxErr--;
  pCheck->nErr++;
  va_start(ap, zFormat);
  if( pCheck->errMsg.nChar ){
    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
  }
  if( pCheck->zPfx ){
    sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2);
    sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf);
  }
  sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
  va_end(ap);
  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
    pCheck->mallocFailed = 1;
  }
}
59952
59953
59954
59955
59956
59957
59958
59959
59960
59961
59962
59963
59964
59965
59966
59967
59968
59969
59970
59971
59972
59973
59974
59975
59976
59977
59978
59979
59980
59981
59982
59983
59984
59985
59986
59987
59988
59989
59990
59991
59992
59993
59994
59995
59996
59997
59998
59999
60000
60001
60002
60003
60004
60005
60006
60007
60008
60009
60010
60011
60012
60013
60014
60015
60016
60017
60018
60019
60020
60021
60022
60023
60024
60025
60026
60027
60028
60029
60030
60031
60032
60033
60034
60035
60036
60037
60038
60039
60040
60041
60042
60043
60044
60045
60046
60047
60048
60049
60050
60051
60052
60053
60054
60055
60056
60057
60058
60059
60060
60061
60062
60063
60064
60065
60066
60067
60068
60069
60070
60071
60072
60073
** Add 1 to the reference count for page iPage.  If this is the second
** reference to the page, add an error message to pCheck->zErrMsg.
** Return 1 if there are 2 or more references to the page and 0 if
** if this is the first reference to the page.
**
** Also check that the page number is in bounds.
*/
static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
  if( iPage==0 ) return 1;
  if( iPage>pCheck->nPage ){
    checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
    return 1;
  }
  if( getPageReferenced(pCheck, iPage) ){
    checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
    return 1;
  }
  setPageReferenced(pCheck, iPage);
  return 0;
}

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Check that the entry in the pointer-map for page iChild maps to 
** page iParent, pointer type ptrType. If not, append an error message
** to pCheck.
*/
static void checkPtrmap(
  IntegrityCk *pCheck,   /* Integrity check context */
  Pgno iChild,           /* Child page number */
  u8 eType,              /* Expected pointer map type */
  Pgno iParent,          /* Expected pointer map parent page number */
  char *zContext         /* Context description (used for error msg) */
){
  int rc;
  u8 ePtrmapType;
  Pgno iPtrmapParent;

  rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
    checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
    return;
  }

  if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
    checkAppendMsg(pCheck, zContext, 
      "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", 
      iChild, eType, iParent, ePtrmapType, iPtrmapParent);
  }
}
#endif

/*
** Check the integrity of the freelist or of an overflow page list.
** Verify that the number of pages on the list is N.
*/
static void checkList(
  IntegrityCk *pCheck,  /* Integrity checking context */
  int isFreeList,       /* True for a freelist.  False for overflow page list */
  int iPage,            /* Page number for first page in the list */
  int N,                /* Expected number of pages in the list */
  char *zContext        /* Context for error messages */
){
  int i;
  int expected = N;
  int iFirst = iPage;
  while( N-- > 0 && pCheck->mxErr ){
    DbPage *pOvflPage;
    unsigned char *pOvflData;
    if( iPage<1 ){
      checkAppendMsg(pCheck, zContext,
         "%d of %d pages missing from overflow list starting at %d",
          N+1, expected, iFirst);
      break;
    }
    if( checkRef(pCheck, iPage, zContext) ) break;
    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
      checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
      break;
    }
    pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
    if( isFreeList ){
      int n = get4byte(&pOvflData[4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pCheck->pBt->autoVacuum ){
        checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
      }
#endif
      if( n>(int)pCheck->pBt->usableSize/4-2 ){
        checkAppendMsg(pCheck, zContext,
           "freelist leaf count too big on page %d", iPage);
        N--;
      }else{
        for(i=0; i<n; i++){
          Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
          if( pCheck->pBt->autoVacuum ){
            checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
          }
#endif
          checkRef(pCheck, iFreePage, zContext);
        }
        N -= n;
      }
    }
#ifndef SQLITE_OMIT_AUTOVACUUM
    else{
      /* If this database supports auto-vacuum and iPage is not the last
      ** page in this overflow list, check that the pointer-map entry for
      ** the following page matches iPage.
      */
      if( pCheck->pBt->autoVacuum && N>0 ){
        i = get4byte(pOvflData);
        checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
      }
    }
#endif
    iPage = get4byte(pOvflData);
    sqlite3PagerUnref(pOvflPage);
  }
}







|


|



|
















|
<








|




|














|
<








|




|

|







|



|







|


|












|







60822
60823
60824
60825
60826
60827
60828
60829
60830
60831
60832
60833
60834
60835
60836
60837
60838
60839
60840
60841
60842
60843
60844
60845
60846
60847
60848
60849
60850
60851
60852
60853

60854
60855
60856
60857
60858
60859
60860
60861
60862
60863
60864
60865
60866
60867
60868
60869
60870
60871
60872
60873
60874
60875
60876
60877
60878
60879
60880
60881
60882

60883
60884
60885
60886
60887
60888
60889
60890
60891
60892
60893
60894
60895
60896
60897
60898
60899
60900
60901
60902
60903
60904
60905
60906
60907
60908
60909
60910
60911
60912
60913
60914
60915
60916
60917
60918
60919
60920
60921
60922
60923
60924
60925
60926
60927
60928
60929
60930
60931
60932
60933
60934
60935
60936
60937
60938
60939
60940
60941
** Add 1 to the reference count for page iPage.  If this is the second
** reference to the page, add an error message to pCheck->zErrMsg.
** Return 1 if there are 2 or more references to the page and 0 if
** if this is the first reference to the page.
**
** Also check that the page number is in bounds.
*/
static int checkRef(IntegrityCk *pCheck, Pgno iPage){
  if( iPage==0 ) return 1;
  if( iPage>pCheck->nPage ){
    checkAppendMsg(pCheck, "invalid page number %d", iPage);
    return 1;
  }
  if( getPageReferenced(pCheck, iPage) ){
    checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
    return 1;
  }
  setPageReferenced(pCheck, iPage);
  return 0;
}

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Check that the entry in the pointer-map for page iChild maps to 
** page iParent, pointer type ptrType. If not, append an error message
** to pCheck.
*/
static void checkPtrmap(
  IntegrityCk *pCheck,   /* Integrity check context */
  Pgno iChild,           /* Child page number */
  u8 eType,              /* Expected pointer map type */
  Pgno iParent           /* Expected pointer map parent page number */

){
  int rc;
  u8 ePtrmapType;
  Pgno iPtrmapParent;

  rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
    checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild);
    return;
  }

  if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
    checkAppendMsg(pCheck,
      "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", 
      iChild, eType, iParent, ePtrmapType, iPtrmapParent);
  }
}
#endif

/*
** Check the integrity of the freelist or of an overflow page list.
** Verify that the number of pages on the list is N.
*/
static void checkList(
  IntegrityCk *pCheck,  /* Integrity checking context */
  int isFreeList,       /* True for a freelist.  False for overflow page list */
  int iPage,            /* Page number for first page in the list */
  int N                 /* Expected number of pages in the list */

){
  int i;
  int expected = N;
  int iFirst = iPage;
  while( N-- > 0 && pCheck->mxErr ){
    DbPage *pOvflPage;
    unsigned char *pOvflData;
    if( iPage<1 ){
      checkAppendMsg(pCheck,
         "%d of %d pages missing from overflow list starting at %d",
          N+1, expected, iFirst);
      break;
    }
    if( checkRef(pCheck, iPage) ) break;
    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
      checkAppendMsg(pCheck, "failed to get page %d", iPage);
      break;
    }
    pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
    if( isFreeList ){
      int n = get4byte(&pOvflData[4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pCheck->pBt->autoVacuum ){
        checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
      }
#endif
      if( n>(int)pCheck->pBt->usableSize/4-2 ){
        checkAppendMsg(pCheck,
           "freelist leaf count too big on page %d", iPage);
        N--;
      }else{
        for(i=0; i<n; i++){
          Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
          if( pCheck->pBt->autoVacuum ){
            checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0);
          }
#endif
          checkRef(pCheck, iFreePage);
        }
        N -= n;
      }
    }
#ifndef SQLITE_OMIT_AUTOVACUUM
    else{
      /* If this database supports auto-vacuum and iPage is not the last
      ** page in this overflow list, check that the pointer-map entry for
      ** the following page matches iPage.
      */
      if( pCheck->pBt->autoVacuum && N>0 ){
        i = get4byte(pOvflData);
        checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage);
      }
    }
#endif
    iPage = get4byte(pOvflData);
    sqlite3PagerUnref(pOvflPage);
  }
}
60091
60092
60093
60094
60095
60096
60097
60098
60099
60100
60101
60102
60103
60104
60105
60106
60107
60108
60109
60110
60111
60112
60113
60114

60115
60116
60117
60118
60119
60120
60121


60122
60123
60124
60125

60126
60127
60128
60129
60130
60131
60132
60133
60134
60135
60136

60137
60138
60139
60140
60141
60142
60143
60144
60145
60146
60147
60148
60149
60150


60151
60152
60153
60154
60155
60156


60157
60158
60159
60160
60161
60162
60163
60164
60165
60166
60167
60168
60169
60170
60171
60172
60173
60174
60175
60176
60177
60178
60179
60180
60181
60182
60183
60184
60185
60186
60187
60188
60189
60190
60191
60192
60193
60194
60195
60196
60197
60198
60199

60200
60201
60202
60203
60204
60205
60206
60207
60208
60209
60210


60211
60212
60213
60214
60215
60216
60217
60218
60219
60220
60221
60222
60223
60224
60225
60226
60227
60228
60229
60230
60231
60232
60233
60234
60235
60236
60237
60238
60239
60240
60241
60242
60243
60244
60245
60246
60247
60248

60249
60250
60251
60252
60253
60254
60255


60256


60257


60258
60259
60260
60261
60262
60263
60264
60265

60266
60267
60268
60269
60270
60271



60272
60273
60274
60275
60276
60277
60278




60279


60280
60281
60282
60283
60284
60285
60286
60287
60288
60289
60290
60291
60292





60293
60294
60295
60296
60297
60298
60299
60300





60301
60302
60303
60304
60305
60306
60307
**      7.  Verify that the depth of all children is the same.
**      8.  Make sure this page is at least 33% full or else it is
**          the root of the tree.
*/
static int checkTreePage(
  IntegrityCk *pCheck,  /* Context for the sanity check */
  int iPage,            /* Page number of the page to check */
  char *zParentContext, /* Parent context */
  i64 *pnParentMinKey, 
  i64 *pnParentMaxKey
){
  MemPage *pPage;
  int i, rc, depth, d2, pgno, cnt;
  int hdr, cellStart;
  int nCell;
  u8 *data;
  BtShared *pBt;
  int usableSize;
  char zContext[100];
  char *hit = 0;
  i64 nMinKey = 0;
  i64 nMaxKey = 0;

  sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);


  /* Check that the page exists
  */
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;


  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
    checkAppendMsg(pCheck, zContext,
       "unable to get the page. error code=%d", rc);
    return 0;

  }

  /* Clear MemPage.isInit to make sure the corruption detection code in
  ** btreeInitPage() is executed.  */
  pPage->isInit = 0;
  if( (rc = btreeInitPage(pPage))!=0 ){
    assert( rc==SQLITE_CORRUPT );  /* The only possible error from InitPage */
    checkAppendMsg(pCheck, zContext, 
                   "btreeInitPage() returns error code %d", rc);
    releasePage(pPage);
    return 0;

  }

  /* Check out all the cells.
  */
  depth = 0;
  for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
    u8 *pCell;
    u32 sz;
    CellInfo info;

    /* Check payload overflow pages
    */
    sqlite3_snprintf(sizeof(zContext), zContext,
             "On tree page %d cell %d: ", iPage, i);


    pCell = findCell(pPage,i);
    btreeParseCellPtr(pPage, pCell, &info);
    sz = info.nData;
    if( !pPage->intKey ) sz += (int)info.nKey;
    /* For intKey pages, check that the keys are in order.
    */


    else if( i==0 ) nMinKey = nMaxKey = info.nKey;
    else{
      if( info.nKey <= nMaxKey ){
        checkAppendMsg(pCheck, zContext, 
            "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
      }
      nMaxKey = info.nKey;
    }
    assert( sz==info.nPayload );
    if( (sz>info.nLocal) 
     && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
    ){
      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
      Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
      }
#endif
      checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
    }

    /* Check sanity of left child page.
    */
    if( !pPage->leaf ){
      pgno = get4byte(pCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
      }
#endif
      d2 = checkTreePage(pCheck, pgno, zContext, &nMinKey, i==0 ? NULL : &nMaxKey);
      if( i>0 && d2!=depth ){
        checkAppendMsg(pCheck, zContext, "Child page depth differs");
      }
      depth = d2;
    }
  }

  if( !pPage->leaf ){
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    sqlite3_snprintf(sizeof(zContext), zContext, 
                     "On page %d at right child: ", iPage);

#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum ){
      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
    }
#endif
    checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
  }
 
  /* For intKey leaf pages, check that the min/max keys are in order
  ** with any left/parent/right pages.
  */


  if( pPage->leaf && pPage->intKey ){
    /* if we are a left child page */
    if( pnParentMinKey ){
      /* if we are the left most child page */
      if( !pnParentMaxKey ){
        if( nMaxKey > *pnParentMinKey ){
          checkAppendMsg(pCheck, zContext, 
              "Rowid %lld out of order (max larger than parent min of %lld)",
              nMaxKey, *pnParentMinKey);
        }
      }else{
        if( nMinKey <= *pnParentMinKey ){
          checkAppendMsg(pCheck, zContext, 
              "Rowid %lld out of order (min less than parent min of %lld)",
              nMinKey, *pnParentMinKey);
        }
        if( nMaxKey > *pnParentMaxKey ){
          checkAppendMsg(pCheck, zContext, 
              "Rowid %lld out of order (max larger than parent max of %lld)",
              nMaxKey, *pnParentMaxKey);
        }
        *pnParentMinKey = nMaxKey;
      }
    /* else if we're a right child page */
    } else if( pnParentMaxKey ){
      if( nMinKey <= *pnParentMaxKey ){
        checkAppendMsg(pCheck, zContext, 
            "Rowid %lld out of order (min less than parent max of %lld)",
            nMinKey, *pnParentMaxKey);
      }
    }
  }

  /* Check for complete coverage of the page
  */
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  hit = sqlite3PageMalloc( pBt->pageSize );

  if( hit==0 ){
    pCheck->mallocFailed = 1;
  }else{
    int contentOffset = get2byteNotZero(&data[hdr+5]);
    assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
    memset(hit+contentOffset, 0, usableSize-contentOffset);
    memset(hit, 1, contentOffset);


    nCell = get2byte(&data[hdr+3]);


    cellStart = hdr + 12 - 4*pPage->leaf;


    for(i=0; i<nCell; i++){
      int pc = get2byte(&data[cellStart+i*2]);
      u32 size = 65536;
      int j;
      if( pc<=usableSize-4 ){
        size = cellSizePtr(pPage, &data[pc]);
      }
      if( (int)(pc+size-1)>=usableSize ){

        checkAppendMsg(pCheck, 0, 
            "Corruption detected in cell %d on page %d",i,iPage);
      }else{
        for(j=pc+size-1; j>=pc; j--) hit[j]++;
      }
    }



    i = get2byte(&data[hdr+1]);
    while( i>0 ){
      int size, j;
      assert( i<=usableSize-4 );     /* Enforced by btreeInitPage() */
      size = get2byte(&data[i+2]);
      assert( i+size<=usableSize );  /* Enforced by btreeInitPage() */
      for(j=i+size-1; j>=i; j--) hit[j]++;




      j = get2byte(&data[i]);


      assert( j==0 || j>i+size );  /* Enforced by btreeInitPage() */
      assert( j<=usableSize-4 );   /* Enforced by btreeInitPage() */
      i = j;
    }
    for(i=cnt=0; i<usableSize; i++){
      if( hit[i]==0 ){
        cnt++;
      }else if( hit[i]>1 ){
        checkAppendMsg(pCheck, 0,
          "Multiple uses for byte %d of page %d", i, iPage);
        break;
      }
    }





    if( cnt!=data[hdr+7] ){
      checkAppendMsg(pCheck, 0, 
          "Fragmentation of %d bytes reported as %d on page %d",
          cnt, data[hdr+7], iPage);
    }
  }
  sqlite3PageFree(hit);
  releasePage(pPage);





  return depth+1;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** This routine does a complete check of the given BTree file.  aRoot[] is







<










<



|
|
>






|
>
>

|

|
>







|


|
>












<
|
>
>


|
<


>
>
|
<
|
|
|



<







|


|








|


|

|







<
|
>


|


|





>
>






|





|




|








|











>







>
>

>
>

>
>








>
|





>
>
>







>
>
>
>

>
>








|




>
>
>
>
>

|






>
>
>
>
>







60959
60960
60961
60962
60963
60964
60965

60966
60967
60968
60969
60970
60971
60972
60973
60974
60975

60976
60977
60978
60979
60980
60981
60982
60983
60984
60985
60986
60987
60988
60989
60990
60991
60992
60993
60994
60995
60996
60997
60998
60999
61000
61001
61002
61003
61004
61005
61006
61007
61008
61009
61010
61011
61012
61013
61014
61015
61016
61017
61018
61019

61020
61021
61022
61023
61024
61025

61026
61027
61028
61029
61030

61031
61032
61033
61034
61035
61036

61037
61038
61039
61040
61041
61042
61043
61044
61045
61046
61047
61048
61049
61050
61051
61052
61053
61054
61055
61056
61057
61058
61059
61060
61061
61062
61063
61064
61065
61066
61067
61068

61069
61070
61071
61072
61073
61074
61075
61076
61077
61078
61079
61080
61081
61082
61083
61084
61085
61086
61087
61088
61089
61090
61091
61092
61093
61094
61095
61096
61097
61098
61099
61100
61101
61102
61103
61104
61105
61106
61107
61108
61109
61110
61111
61112
61113
61114
61115
61116
61117
61118
61119
61120
61121
61122
61123
61124
61125
61126
61127
61128
61129
61130
61131
61132
61133
61134
61135
61136
61137
61138
61139
61140
61141
61142
61143
61144
61145
61146
61147
61148
61149
61150
61151
61152
61153
61154
61155
61156
61157
61158
61159
61160
61161
61162
61163
61164
61165
61166
61167
61168
61169
61170
61171
61172
61173
61174
61175
61176
61177
61178
61179
61180
61181
61182
61183
61184
61185
61186
61187
61188
61189
61190
61191
61192
61193
61194
61195
61196
61197
61198
61199
61200
61201
61202
61203
61204
61205
61206
61207
**      7.  Verify that the depth of all children is the same.
**      8.  Make sure this page is at least 33% full or else it is
**          the root of the tree.
*/
static int checkTreePage(
  IntegrityCk *pCheck,  /* Context for the sanity check */
  int iPage,            /* Page number of the page to check */

  i64 *pnParentMinKey, 
  i64 *pnParentMaxKey
){
  MemPage *pPage;
  int i, rc, depth, d2, pgno, cnt;
  int hdr, cellStart;
  int nCell;
  u8 *data;
  BtShared *pBt;
  int usableSize;

  char *hit = 0;
  i64 nMinKey = 0;
  i64 nMaxKey = 0;
  const char *saved_zPfx = pCheck->zPfx;
  int saved_v1 = pCheck->v1;
  int saved_v2 = pCheck->v2;

  /* Check that the page exists
  */
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage) ) return 0;
  pCheck->zPfx = "Page %d: ";
  pCheck->v1 = iPage;
  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
    checkAppendMsg(pCheck,
       "unable to get the page. error code=%d", rc);
    depth = -1;
    goto end_of_check;
  }

  /* Clear MemPage.isInit to make sure the corruption detection code in
  ** btreeInitPage() is executed.  */
  pPage->isInit = 0;
  if( (rc = btreeInitPage(pPage))!=0 ){
    assert( rc==SQLITE_CORRUPT );  /* The only possible error from InitPage */
    checkAppendMsg(pCheck,
                   "btreeInitPage() returns error code %d", rc);
    releasePage(pPage);
    depth = -1;
    goto end_of_check;
  }

  /* Check out all the cells.
  */
  depth = 0;
  for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
    u8 *pCell;
    u32 sz;
    CellInfo info;

    /* Check payload overflow pages
    */

    pCheck->zPfx = "On tree page %d cell %d: ";
    pCheck->v1 = iPage;
    pCheck->v2 = i;
    pCell = findCell(pPage,i);
    btreeParseCellPtr(pPage, pCell, &info);
    sz = info.nPayload;

    /* For intKey pages, check that the keys are in order.
    */
    if( pPage->intKey ){
      if( i==0 ){
        nMinKey = nMaxKey = info.nKey;

      }else if( info.nKey <= nMaxKey ){
        checkAppendMsg(pCheck,
           "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
      }
      nMaxKey = info.nKey;
    }

    if( (sz>info.nLocal) 
     && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
    ){
      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
      Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
      }
#endif
      checkList(pCheck, 0, pgnoOvfl, nPage);
    }

    /* Check sanity of left child page.
    */
    if( !pPage->leaf ){
      pgno = get4byte(pCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
      }
#endif
      d2 = checkTreePage(pCheck, pgno, &nMinKey, i==0?NULL:&nMaxKey);
      if( i>0 && d2!=depth ){
        checkAppendMsg(pCheck, "Child page depth differs");
      }
      depth = d2;
    }
  }

  if( !pPage->leaf ){
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);

    pCheck->zPfx = "On page %d at right child: ";
    pCheck->v1 = iPage;
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum ){
      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
    }
#endif
    checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey);
  }
 
  /* For intKey leaf pages, check that the min/max keys are in order
  ** with any left/parent/right pages.
  */
  pCheck->zPfx = "Page %d: ";
  pCheck->v1 = iPage;
  if( pPage->leaf && pPage->intKey ){
    /* if we are a left child page */
    if( pnParentMinKey ){
      /* if we are the left most child page */
      if( !pnParentMaxKey ){
        if( nMaxKey > *pnParentMinKey ){
          checkAppendMsg(pCheck,
              "Rowid %lld out of order (max larger than parent min of %lld)",
              nMaxKey, *pnParentMinKey);
        }
      }else{
        if( nMinKey <= *pnParentMinKey ){
          checkAppendMsg(pCheck,
              "Rowid %lld out of order (min less than parent min of %lld)",
              nMinKey, *pnParentMinKey);
        }
        if( nMaxKey > *pnParentMaxKey ){
          checkAppendMsg(pCheck,
              "Rowid %lld out of order (max larger than parent max of %lld)",
              nMaxKey, *pnParentMaxKey);
        }
        *pnParentMinKey = nMaxKey;
      }
    /* else if we're a right child page */
    } else if( pnParentMaxKey ){
      if( nMinKey <= *pnParentMaxKey ){
        checkAppendMsg(pCheck,
            "Rowid %lld out of order (min less than parent max of %lld)",
            nMinKey, *pnParentMaxKey);
      }
    }
  }

  /* Check for complete coverage of the page
  */
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  hit = sqlite3PageMalloc( pBt->pageSize );
  pCheck->zPfx = 0;
  if( hit==0 ){
    pCheck->mallocFailed = 1;
  }else{
    int contentOffset = get2byteNotZero(&data[hdr+5]);
    assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
    memset(hit+contentOffset, 0, usableSize-contentOffset);
    memset(hit, 1, contentOffset);
    /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
    ** number of cells on the page. */
    nCell = get2byte(&data[hdr+3]);
    /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
    ** immediately follows the b-tree page header. */
    cellStart = hdr + 12 - 4*pPage->leaf;
    /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
    ** integer offsets to the cell contents. */
    for(i=0; i<nCell; i++){
      int pc = get2byte(&data[cellStart+i*2]);
      u32 size = 65536;
      int j;
      if( pc<=usableSize-4 ){
        size = cellSizePtr(pPage, &data[pc]);
      }
      if( (int)(pc+size-1)>=usableSize ){
        pCheck->zPfx = 0;
        checkAppendMsg(pCheck,
            "Corruption detected in cell %d on page %d",i,iPage);
      }else{
        for(j=pc+size-1; j>=pc; j--) hit[j]++;
      }
    }
    /* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
    ** is the offset of the first freeblock, or zero if there are no
    ** freeblocks on the page. */
    i = get2byte(&data[hdr+1]);
    while( i>0 ){
      int size, j;
      assert( i<=usableSize-4 );     /* Enforced by btreeInitPage() */
      size = get2byte(&data[i+2]);
      assert( i+size<=usableSize );  /* Enforced by btreeInitPage() */
      for(j=i+size-1; j>=i; j--) hit[j]++;
      /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
      ** big-endian integer which is the offset in the b-tree page of the next
      ** freeblock in the chain, or zero if the freeblock is the last on the
      ** chain. */
      j = get2byte(&data[i]);
      /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
      ** increasing offset. */
      assert( j==0 || j>i+size );  /* Enforced by btreeInitPage() */
      assert( j<=usableSize-4 );   /* Enforced by btreeInitPage() */
      i = j;
    }
    for(i=cnt=0; i<usableSize; i++){
      if( hit[i]==0 ){
        cnt++;
      }else if( hit[i]>1 ){
        checkAppendMsg(pCheck,
          "Multiple uses for byte %d of page %d", i, iPage);
        break;
      }
    }
    /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
    ** is stored in the fifth field of the b-tree page header.
    ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
    ** number of fragmented free bytes within the cell content area.
    */
    if( cnt!=data[hdr+7] ){
      checkAppendMsg(pCheck,
          "Fragmentation of %d bytes reported as %d on page %d",
          cnt, data[hdr+7], iPage);
    }
  }
  sqlite3PageFree(hit);
  releasePage(pPage);

end_of_check:
  pCheck->zPfx = saved_zPfx;
  pCheck->v1 = saved_v1;
  pCheck->v2 = saved_v2;
  return depth+1;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** This routine does a complete check of the given BTree file.  aRoot[] is
60334
60335
60336
60337
60338
60339
60340



60341
60342
60343
60344
60345
60346
60347
60348
60349
60350
60351
60352
60353
60354
60355
60356
60357
60358
60359

60360
60361

60362
60363
60364
60365
60366
60367
60368
60369
60370
60371

60372

60373
60374
60375
60376
60377
60378
60379
60380
60381
60382
60383
60384
60385
60386
60387
60388
60389
60390
60391
60392
60393
60394
60395
60396
60397
60398
60399
60400
60401
60402
60403
60404
60405
60406
60407
60408
60409
  nRef = sqlite3PagerRefcount(pBt->pPager);
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = btreePagecount(sCheck.pBt);
  sCheck.mxErr = mxErr;
  sCheck.nErr = 0;
  sCheck.mallocFailed = 0;



  *pnErr = 0;
  if( sCheck.nPage==0 ){
    sqlite3BtreeLeave(p);
    return 0;
  }

  sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
  if( !sCheck.aPgRef ){
    *pnErr = 1;
    sqlite3BtreeLeave(p);
    return 0;
  }
  i = PENDING_BYTE_PAGE(pBt);
  if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
  sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
  sCheck.errMsg.useMalloc = 2;

  /* Check the integrity of the freelist
  */

  checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
            get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");


  /* Check all the tables.
  */
  for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
    if( aRoot[i]==0 ) continue;
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum && aRoot[i]>1 ){
      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
    }
#endif

    checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);

  }

  /* Make sure every page in the file is referenced
  */
  for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
    if( getPageReferenced(&sCheck, i)==0 ){
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
    }
#else
    /* If the database supports auto-vacuum, make sure no tables contain
    ** references to pointer-map pages.
    */
    if( getPageReferenced(&sCheck, i)==0 && 
       (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
    }
    if( getPageReferenced(&sCheck, i)!=0 && 
       (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
    }
#endif
  }

  /* Make sure this analysis did not leave any unref() pages.
  ** This is an internal consistency check; an integrity check
  ** of the integrity check.
  */
  if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
    checkAppendMsg(&sCheck, 0, 
      "Outstanding page count goes from %d to %d during this analysis",
      nRef, sqlite3PagerRefcount(pBt->pPager)
    );
  }

  /* Clean  up and report errors.
  */







>
>
>



















>

|
>







|


>
|
>







|







|



|









|







61234
61235
61236
61237
61238
61239
61240
61241
61242
61243
61244
61245
61246
61247
61248
61249
61250
61251
61252
61253
61254
61255
61256
61257
61258
61259
61260
61261
61262
61263
61264
61265
61266
61267
61268
61269
61270
61271
61272
61273
61274
61275
61276
61277
61278
61279
61280
61281
61282
61283
61284
61285
61286
61287
61288
61289
61290
61291
61292
61293
61294
61295
61296
61297
61298
61299
61300
61301
61302
61303
61304
61305
61306
61307
61308
61309
61310
61311
61312
61313
61314
61315
61316
  nRef = sqlite3PagerRefcount(pBt->pPager);
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = btreePagecount(sCheck.pBt);
  sCheck.mxErr = mxErr;
  sCheck.nErr = 0;
  sCheck.mallocFailed = 0;
  sCheck.zPfx = 0;
  sCheck.v1 = 0;
  sCheck.v2 = 0;
  *pnErr = 0;
  if( sCheck.nPage==0 ){
    sqlite3BtreeLeave(p);
    return 0;
  }

  sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
  if( !sCheck.aPgRef ){
    *pnErr = 1;
    sqlite3BtreeLeave(p);
    return 0;
  }
  i = PENDING_BYTE_PAGE(pBt);
  if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
  sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
  sCheck.errMsg.useMalloc = 2;

  /* Check the integrity of the freelist
  */
  sCheck.zPfx = "Main freelist: ";
  checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
            get4byte(&pBt->pPage1->aData[36]));
  sCheck.zPfx = 0;

  /* Check all the tables.
  */
  for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
    if( aRoot[i]==0 ) continue;
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum && aRoot[i]>1 ){
      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
    }
#endif
    sCheck.zPfx = "List of tree roots: ";
    checkTreePage(&sCheck, aRoot[i], NULL, NULL);
    sCheck.zPfx = 0;
  }

  /* Make sure every page in the file is referenced
  */
  for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
    if( getPageReferenced(&sCheck, i)==0 ){
      checkAppendMsg(&sCheck, "Page %d is never used", i);
    }
#else
    /* If the database supports auto-vacuum, make sure no tables contain
    ** references to pointer-map pages.
    */
    if( getPageReferenced(&sCheck, i)==0 && 
       (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, "Page %d is never used", i);
    }
    if( getPageReferenced(&sCheck, i)!=0 && 
       (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
    }
#endif
  }

  /* Make sure this analysis did not leave any unref() pages.
  ** This is an internal consistency check; an integrity check
  ** of the integrity check.
  */
  if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
    checkAppendMsg(&sCheck,
      "Outstanding page count goes from %d to %d during this analysis",
      nRef, sqlite3PagerRefcount(pBt->pPager)
    );
  }

  /* Clean  up and report errors.
  */
60591
60592
60593
60594
60595
60596
60597
60598
60599
60600
60601
60602
60603
60604
60605
    return SQLITE_ABORT;
  }

  /* Save the positions of all other cursors open on this table. This is
  ** required in case any of them are holding references to an xFetch
  ** version of the b-tree page modified by the accessPayload call below.
  **
  ** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition()
  ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
  ** saveAllCursors can only return SQLITE_OK.
  */
  VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
  assert( rc==SQLITE_OK );

  /* Check some assumptions: 







|







61498
61499
61500
61501
61502
61503
61504
61505
61506
61507
61508
61509
61510
61511
61512
    return SQLITE_ABORT;
  }

  /* Save the positions of all other cursors open on this table. This is
  ** required in case any of them are holding references to an xFetch
  ** version of the b-tree page modified by the accessPayload call below.
  **
  ** Note that pCsr must be open on a INTKEY table and saveCursorPosition()
  ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
  ** saveAllCursors can only return SQLITE_OK.
  */
  VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
  assert( rc==SQLITE_OK );

  /* Check some assumptions: 
60677
60678
60679
60680
60681
60682
60683





60684
60685
60686
60687
60688
60689
60690
/*
** Return true if the given Btree is read-only.
*/
SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){
  return (p->pBt->btsFlags & BTS_READ_ONLY)!=0;
}






/************** End of btree.c ***********************************************/
/************** Begin file backup.c ******************************************/
/*
** 2009 January 28
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:







>
>
>
>
>







61584
61585
61586
61587
61588
61589
61590
61591
61592
61593
61594
61595
61596
61597
61598
61599
61600
61601
61602
/*
** Return true if the given Btree is read-only.
*/
SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){
  return (p->pBt->btsFlags & BTS_READ_ONLY)!=0;
}

/*
** Return the size of the header added to each page by this module.
*/
SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return sizeof(MemPage); }

/************** End of btree.c ***********************************************/
/************** Begin file backup.c ******************************************/
/*
** 2009 January 28
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
60800
60801
60802
60803
60804
60805
60806














60807
60808
60809
60810
60811
60812
60813
60814
60815
60816
60817
60818
60819
60820
60821
60822







60823
60824
60825
60826
60827
60828
60829
** of the source.
*/
static int setDestPgsz(sqlite3_backup *p){
  int rc;
  rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
  return rc;
}















/*
** Create an sqlite3_backup process to copy the contents of zSrcDb from
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
** a pointer to the new sqlite3_backup object.
**
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
  sqlite3* pDestDb,                     /* Database to write to */
  const char *zDestDb,                  /* Name of database within pDestDb */
  sqlite3* pSrcDb,                      /* Database connection to read from */
  const char *zSrcDb                    /* Name of database within pSrcDb */
){
  sqlite3_backup *p;                    /* Value to return */








  /* Lock the source database handle. The destination database
  ** handle is not locked in this routine, but it is locked in
  ** sqlite3_backup_step(). The user is required to ensure that no
  ** other thread accesses the destination handle for the duration
  ** of the backup operation.  Any attempt to use the destination
  ** database connection while a backup is in progress may cause







>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>
>
>
>
>
>
>







61712
61713
61714
61715
61716
61717
61718
61719
61720
61721
61722
61723
61724
61725
61726
61727
61728
61729
61730
61731
61732
61733
61734
61735
61736
61737
61738
61739
61740
61741
61742
61743
61744
61745
61746
61747
61748
61749
61750
61751
61752
61753
61754
61755
61756
61757
61758
61759
61760
61761
61762
** of the source.
*/
static int setDestPgsz(sqlite3_backup *p){
  int rc;
  rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
  return rc;
}

/*
** Check that there is no open read-transaction on the b-tree passed as the
** second argument. If there is not, return SQLITE_OK. Otherwise, if there
** is an open read-transaction, return SQLITE_ERROR and leave an error 
** message in database handle db.
*/
static int checkReadTransaction(sqlite3 *db, Btree *p){
  if( sqlite3BtreeIsInReadTrans(p) ){
    sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}

/*
** Create an sqlite3_backup process to copy the contents of zSrcDb from
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
** a pointer to the new sqlite3_backup object.
**
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
  sqlite3* pDestDb,                     /* Database to write to */
  const char *zDestDb,                  /* Name of database within pDestDb */
  sqlite3* pSrcDb,                      /* Database connection to read from */
  const char *zSrcDb                    /* Name of database within pSrcDb */
){
  sqlite3_backup *p;                    /* Value to return */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif

  /* Lock the source database handle. The destination database
  ** handle is not locked in this routine, but it is locked in
  ** sqlite3_backup_step(). The user is required to ensure that no
  ** other thread accesses the destination handle for the duration
  ** of the backup operation.  Any attempt to use the destination
  ** database connection while a backup is in progress may cause
60853
60854
60855
60856
60857
60858
60859
60860



60861

60862
60863
60864
60865
60866
60867
60868
60869
60870
60871
60872
    p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
    p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
    p->pDestDb = pDestDb;
    p->pSrcDb = pSrcDb;
    p->iNext = 1;
    p->isAttached = 0;

    if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){



      /* One (or both) of the named databases did not exist or an OOM

      ** error was hit.  The error has already been written into the
      ** pDestDb handle.  All that is left to do here is free the
      ** sqlite3_backup structure.
      */
      sqlite3_free(p);
      p = 0;
    }
  }
  if( p ){
    p->pSrc->nBackup++;
  }







|
>
>
>

>
|
|
|
<







61786
61787
61788
61789
61790
61791
61792
61793
61794
61795
61796
61797
61798
61799
61800
61801

61802
61803
61804
61805
61806
61807
61808
    p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
    p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
    p->pDestDb = pDestDb;
    p->pSrcDb = pSrcDb;
    p->iNext = 1;
    p->isAttached = 0;

    if( 0==p->pSrc || 0==p->pDest 
     || setDestPgsz(p)==SQLITE_NOMEM 
     || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK 
     ){
      /* One (or both) of the named databases did not exist or an OOM
      ** error was hit. Or there is a transaction open on the destination
      ** database. The error has already been written into the pDestDb 
      ** handle. All that is left to do here is free the sqlite3_backup 
      ** structure.  */

      sqlite3_free(p);
      p = 0;
    }
  }
  if( p ){
    p->pSrc->nBackup++;
  }
61013
61014
61015
61016
61017
61018
61019



61020
61021
61022
61023
61024
61025
61026
*/
SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
  int rc;
  int destMode;       /* Destination journal mode */
  int pgszSrc = 0;    /* Source page size */
  int pgszDest = 0;   /* Destination page size */




  sqlite3_mutex_enter(p->pSrcDb->mutex);
  sqlite3BtreeEnter(p->pSrc);
  if( p->pDestDb ){
    sqlite3_mutex_enter(p->pDestDb->mutex);
  }

  rc = p->rc;







>
>
>







61949
61950
61951
61952
61953
61954
61955
61956
61957
61958
61959
61960
61961
61962
61963
61964
61965
*/
SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
  int rc;
  int destMode;       /* Destination journal mode */
  int pgszSrc = 0;    /* Source page size */
  int pgszDest = 0;   /* Destination page size */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( p==0 ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(p->pSrcDb->mutex);
  sqlite3BtreeEnter(p->pSrc);
  if( p->pDestDb ){
    sqlite3_mutex_enter(p->pDestDb->mutex);
  }

  rc = p->rc;
61276
61277
61278
61279
61280
61281
61282
61283
61284
61285
61286
61287
61288
61289
61290
    while( *pp!=p ){
      pp = &(*pp)->pNext;
    }
    *pp = p->pNext;
  }

  /* If a transaction is still open on the Btree, roll it back. */
  sqlite3BtreeRollback(p->pDest, SQLITE_OK);

  /* Set the error code of the destination database handle. */
  rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
  if( p->pDestDb ){
    sqlite3Error(p->pDestDb, rc);

    /* Exit the mutexes and free the backup context structure. */







|







62215
62216
62217
62218
62219
62220
62221
62222
62223
62224
62225
62226
62227
62228
62229
    while( *pp!=p ){
      pp = &(*pp)->pNext;
    }
    *pp = p->pNext;
  }

  /* If a transaction is still open on the Btree, roll it back. */
  sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);

  /* Set the error code of the destination database handle. */
  rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
  if( p->pDestDb ){
    sqlite3Error(p->pDestDb, rc);

    /* Exit the mutexes and free the backup context structure. */
61302
61303
61304
61305
61306
61307
61308






61309
61310
61311
61312
61313
61314
61315
61316






61317
61318
61319
61320
61321
61322
61323
}

/*
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){






  return p->nRemaining;
}

/*
** Return the total number of pages in the source database as of the most 
** recent call to sqlite3_backup_step().
*/
SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){






  return p->nPagecount;
}

/*
** This function is called after the contents of page iPage of the
** source database have been modified. If page iPage has already been 
** copied into the destination database, then the data written to the







>
>
>
>
>
>








>
>
>
>
>
>







62241
62242
62243
62244
62245
62246
62247
62248
62249
62250
62251
62252
62253
62254
62255
62256
62257
62258
62259
62260
62261
62262
62263
62264
62265
62266
62267
62268
62269
62270
62271
62272
62273
62274
}

/*
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( p==0 ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  return p->nRemaining;
}

/*
** Return the total number of pages in the source database as of the most 
** recent call to sqlite3_backup_step().
*/
SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( p==0 ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  return p->nPagecount;
}

/*
** This function is called after the contents of page iPage of the
** source database have been modified. If page iPage has already been 
** copied into the destination database, then the data written to the
61459
61460
61461
61462
61463
61464
61465
61466



61467
61468
61469
61470
61471
61472
61473
*/
SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
  /* If MEM_Dyn is set then Mem.xDel!=0.  
  ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
  */
  assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );

  /* MEM_Dyn may only be set if Mem.szMalloc==0 */



  assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );

  /* Cannot be both MEM_Int and MEM_Real at the same time */
  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );

  /* The szMalloc field holds the correct memory allocation size */
  assert( p->szMalloc==0







|
>
>
>







62410
62411
62412
62413
62414
62415
62416
62417
62418
62419
62420
62421
62422
62423
62424
62425
62426
62427
*/
SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
  /* If MEM_Dyn is set then Mem.xDel!=0.  
  ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
  */
  assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );

  /* MEM_Dyn may only be set if Mem.szMalloc==0.  In this way we
  ** ensure that if Mem.szMalloc>0 then it is safe to do
  ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
  ** That saves a few cycles in inner loops. */
  assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );

  /* Cannot be both MEM_Int and MEM_Real at the same time */
  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );

  /* The szMalloc field holds the correct memory allocation size */
  assert( p->szMalloc==0
61568
61569
61570
61571
61572
61573
61574
61575
61576
61577
61578
61579
61580
61581
61582
      pMem->szMalloc = 0;
      return SQLITE_NOMEM;
    }else{
      pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
    }
  }

  if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
    memcpy(pMem->zMalloc, pMem->z, pMem->n);
  }
  if( (pMem->flags&MEM_Dyn)!=0 ){
    assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
    pMem->xDel((void *)(pMem->z));
  }








|







62522
62523
62524
62525
62526
62527
62528
62529
62530
62531
62532
62533
62534
62535
62536
      pMem->szMalloc = 0;
      return SQLITE_NOMEM;
    }else{
      pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
    }
  }

  if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
    memcpy(pMem->zMalloc, pMem->z, pMem->n);
  }
  if( (pMem->flags&MEM_Dyn)!=0 ){
    assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
    pMem->xDel((void *)(pMem->z));
  }

61595
61596
61597
61598
61599
61600
61601
61602

61603
61604
61605
61606
61607
61608
61609
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
** values are preserved.
**
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
** if unable to complete the resizing.
*/
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
  assert( szNew>=0 );

  if( pMem->szMalloc<szNew ){
    return sqlite3VdbeMemGrow(pMem, szNew, 0);
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  pMem->z = pMem->zMalloc;
  pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
  return SQLITE_OK;







|
>







62549
62550
62551
62552
62553
62554
62555
62556
62557
62558
62559
62560
62561
62562
62563
62564
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
** values are preserved.
**
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
** if unable to complete the resizing.
*/
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
  assert( szNew>0 );
  assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
  if( pMem->szMalloc<szNew ){
    return sqlite3VdbeMemGrow(pMem, szNew, 0);
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  pMem->z = pMem->zMalloc;
  pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
  return SQLITE_OK;
62319
62320
62321
62322
62323
62324
62325



62326
62327
62328
62329
62330
62331
62332
62333
    int nAlloc = nByte;
    if( flags&MEM_Term ){
      nAlloc += (enc==SQLITE_UTF8?1:2);
    }
    if( nByte>iLimit ){
      return SQLITE_TOOBIG;
    }



    if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){
      return SQLITE_NOMEM;
    }
    memcpy(pMem->z, z, nAlloc);
  }else if( xDel==SQLITE_DYNAMIC ){
    sqlite3VdbeMemRelease(pMem);
    pMem->zMalloc = pMem->z = (char *)z;
    pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);







>
>
>
|







63274
63275
63276
63277
63278
63279
63280
63281
63282
63283
63284
63285
63286
63287
63288
63289
63290
63291
    int nAlloc = nByte;
    if( flags&MEM_Term ){
      nAlloc += (enc==SQLITE_UTF8?1:2);
    }
    if( nByte>iLimit ){
      return SQLITE_TOOBIG;
    }
    testcase( nAlloc==0 );
    testcase( nAlloc==31 );
    testcase( nAlloc==32 );
    if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
      return SQLITE_NOMEM;
    }
    memcpy(pMem->z, z, nAlloc);
  }else if( xDel==SQLITE_DYNAMIC ){
    sqlite3VdbeMemRelease(pMem);
    pMem->zMalloc = pMem->z = (char *)z;
    pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
62422
62423
62424
62425
62426
62427
62428
62429
62430
62431
62432
62433
62434
62435
62436
}

/*
** The pVal argument is known to be a value other than NULL.
** Convert it into a string with encoding enc and return a pointer
** to a zero-terminated version of that string.
*/
SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
  assert( pVal!=0 );
  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
  assert( (pVal->flags & MEM_RowSet)==0 );
  assert( (pVal->flags & (MEM_Null))==0 );
  if( pVal->flags & (MEM_Blob|MEM_Str) ){
    pVal->flags |= MEM_Str;







|







63380
63381
63382
63383
63384
63385
63386
63387
63388
63389
63390
63391
63392
63393
63394
}

/*
** The pVal argument is known to be a value other than NULL.
** Convert it into a string with encoding enc and return a pointer
** to a zero-terminated version of that string.
*/
static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
  assert( pVal!=0 );
  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
  assert( (pVal->flags & MEM_RowSet)==0 );
  assert( (pVal->flags & (MEM_Null))==0 );
  if( pVal->flags & (MEM_Blob|MEM_Str) ){
    pVal->flags |= MEM_Str;
63593
63594
63595
63596
63597
63598
63599




























63600
63601
63602
63603
63604
63605
63606
      }
#endif
    }
    p->nOp += nOp;
  }
  return addr;
}





























/*
** Change the value of the P1 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







64551
64552
64553
64554
64555
64556
64557
64558
64559
64560
64561
64562
64563
64564
64565
64566
64567
64568
64569
64570
64571
64572
64573
64574
64575
64576
64577
64578
64579
64580
64581
64582
64583
64584
64585
64586
64587
64588
64589
64590
64591
64592
      }
#endif
    }
    p->nOp += nOp;
  }
  return addr;
}

#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
/*
** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus().
*/
SQLITE_PRIVATE void sqlite3VdbeScanStatus(
  Vdbe *p,                        /* VM to add scanstatus() to */
  int addrExplain,                /* Address of OP_Explain (or 0) */
  int addrLoop,                   /* Address of loop counter */ 
  int addrVisit,                  /* Address of rows visited counter */
  LogEst nEst,                    /* Estimated number of output rows */
  const char *zName               /* Name of table or index being scanned */
){
  int nByte = (p->nScan+1) * sizeof(ScanStatus);
  ScanStatus *aNew;
  aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
  if( aNew ){
    ScanStatus *pNew = &aNew[p->nScan++];
    pNew->addrExplain = addrExplain;
    pNew->addrLoop = addrLoop;
    pNew->addrVisit = addrVisit;
    pNew->nEst = nEst;
    pNew->zName = sqlite3DbStrDup(p->db, zName);
    p->aScan = aNew;
  }
}
#endif


/*
** Change the value of the P1 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
*/
63749
63750
63751
63752
63753
63754
63755
63756

63757
63758
63759
63760
63761
63762
63763
    memset(pOp, 0, sizeof(pOp[0]));
    pOp->opcode = OP_Noop;
    if( addr==p->nOp-1 ) p->nOp--;
  }
}

/*
** Remove the last opcode inserted

*/
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
  if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
    sqlite3VdbeChangeToNoop(p, p->nOp-1);
    return 1;
  }else{
    return 0;







|
>







64735
64736
64737
64738
64739
64740
64741
64742
64743
64744
64745
64746
64747
64748
64749
64750
    memset(pOp, 0, sizeof(pOp[0]));
    pOp->opcode = OP_Noop;
    if( addr==p->nOp-1 ) p->nOp--;
  }
}

/*
** If the last opcode is "op" and it is not a jump destination,
** then remove it.  Return true if and only if an opcode was removed.
*/
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
  if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
    sqlite3VdbeChangeToNoop(p, p->nOp-1);
    return 1;
  }else{
    return 0;
64691
64692
64693
64694
64695
64696
64697



64698
64699
64700
64701
64702
64703
64704
    p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
    p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
    p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
    p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
    p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
                          &zCsr, zEnd, &nByte);
    p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);



    if( nByte ){
      p->pFree = sqlite3DbMallocZero(db, nByte);
    }
    zCsr = p->pFree;
    zEnd = &zCsr[nByte];
  }while( nByte && !db->mallocFailed );








>
>
>







65678
65679
65680
65681
65682
65683
65684
65685
65686
65687
65688
65689
65690
65691
65692
65693
65694
    p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
    p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
    p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
    p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
    p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
                          &zCsr, zEnd, &nByte);
    p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), &zCsr, zEnd, &nByte);
#endif
    if( nByte ){
      p->pFree = sqlite3DbMallocZero(db, nByte);
    }
    zCsr = p->pFree;
    zEnd = &zCsr[nByte];
  }while( nByte && !db->mallocFailed );

64741
64742
64743
64744
64745
64746
64747
64748
64749
64750
64751
64752
64753
64754
64755
64756
64757
64758
64759
64760
64761
64762
64763
64764



64765
64766
64767
64768
64769
64770
64771
64772
64773
64774

64775
64776
64777
64778
64779
64780
64781
64782
64783
64784
64785
64786
64787
64788
64789
64790
64791
64792
64793


64794
64795
64796
64797
64798
64799
64800
    sqlite3BtreeClose(pCx->pBt);
    /* The pCx->pCursor will be close automatically, if it exists, by
    ** the call above. */
  }else if( pCx->pCursor ){
    sqlite3BtreeCloseCursor(pCx->pCursor);
  }
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( pCx->pVtabCursor ){
    sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
    const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
    p->inVtabMethod = 1;
    pModule->xClose(pVtabCursor);
    p->inVtabMethod = 0;
  }
#endif
}

/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
  Vdbe *v = pFrame->v;



  v->aOnceFlag = pFrame->aOnceFlag;
  v->nOnceFlag = pFrame->nOnceFlag;
  v->aOp = pFrame->aOp;
  v->nOp = pFrame->nOp;
  v->aMem = pFrame->aMem;
  v->nMem = pFrame->nMem;
  v->apCsr = pFrame->apCsr;
  v->nCursor = pFrame->nCursor;
  v->db->lastRowid = pFrame->lastRowid;
  v->nChange = pFrame->nChange;

  return pFrame->pc;
}

/*
** Close all cursors.
**
** Also release any dynamic memory held by the VM in the Vdbe.aMem memory 
** cell array. This is necessary as the memory cell array may contain
** pointers to VdbeFrame objects, which may in turn contain pointers to
** open cursors.
*/
static void closeAllCursors(Vdbe *p){
  if( p->pFrame ){
    VdbeFrame *pFrame;
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    sqlite3VdbeFrameRestore(pFrame);
  }
  p->pFrame = 0;
  p->nFrame = 0;



  if( p->apCsr ){
    int i;
    for(i=0; i<p->nCursor; i++){
      VdbeCursor *pC = p->apCsr[i];
      if( pC ){
        sqlite3VdbeFreeCursor(p, pC);







|
















>
>
>










>
















<
|
|
>
>







65731
65732
65733
65734
65735
65736
65737
65738
65739
65740
65741
65742
65743
65744
65745
65746
65747
65748
65749
65750
65751
65752
65753
65754
65755
65756
65757
65758
65759
65760
65761
65762
65763
65764
65765
65766
65767
65768
65769
65770
65771
65772
65773
65774
65775
65776
65777
65778
65779
65780
65781
65782
65783
65784

65785
65786
65787
65788
65789
65790
65791
65792
65793
65794
65795
    sqlite3BtreeClose(pCx->pBt);
    /* The pCx->pCursor will be close automatically, if it exists, by
    ** the call above. */
  }else if( pCx->pCursor ){
    sqlite3BtreeCloseCursor(pCx->pCursor);
  }
#ifndef SQLITE_OMIT_VIRTUALTABLE
  else if( pCx->pVtabCursor ){
    sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
    const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
    p->inVtabMethod = 1;
    pModule->xClose(pVtabCursor);
    p->inVtabMethod = 0;
  }
#endif
}

/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
  Vdbe *v = pFrame->v;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  v->anExec = pFrame->anExec;
#endif
  v->aOnceFlag = pFrame->aOnceFlag;
  v->nOnceFlag = pFrame->nOnceFlag;
  v->aOp = pFrame->aOp;
  v->nOp = pFrame->nOp;
  v->aMem = pFrame->aMem;
  v->nMem = pFrame->nMem;
  v->apCsr = pFrame->apCsr;
  v->nCursor = pFrame->nCursor;
  v->db->lastRowid = pFrame->lastRowid;
  v->nChange = pFrame->nChange;
  v->db->nChange = pFrame->nDbChange;
  return pFrame->pc;
}

/*
** Close all cursors.
**
** Also release any dynamic memory held by the VM in the Vdbe.aMem memory 
** cell array. This is necessary as the memory cell array may contain
** pointers to VdbeFrame objects, which may in turn contain pointers to
** open cursors.
*/
static void closeAllCursors(Vdbe *p){
  if( p->pFrame ){
    VdbeFrame *pFrame;
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    sqlite3VdbeFrameRestore(pFrame);

    p->pFrame = 0;
    p->nFrame = 0;
  }
  assert( p->nFrame==0 );

  if( p->apCsr ){
    int i;
    for(i=0; i<p->nCursor; i++){
      VdbeCursor *pC = p->apCsr[i];
      if( pC ){
        sqlite3VdbeFreeCursor(p, pC);
64808
64809
64810
64811
64812
64813
64814
64815
64816
64817
64818
64819
64820
64821
64822
  while( p->pDelFrame ){
    VdbeFrame *pDel = p->pDelFrame;
    p->pDelFrame = pDel->pParent;
    sqlite3VdbeFrameDelete(pDel);
  }

  /* Delete any auxdata allocations made by the VM */
  sqlite3VdbeDeleteAuxData(p, -1, 0);
  assert( p->pAuxData==0 );
}

/*
** Clean up the VM after a single run.
*/
static void Cleanup(Vdbe *p){







|







65803
65804
65805
65806
65807
65808
65809
65810
65811
65812
65813
65814
65815
65816
65817
  while( p->pDelFrame ){
    VdbeFrame *pDel = p->pDelFrame;
    p->pDelFrame = pDel->pParent;
    sqlite3VdbeFrameDelete(pDel);
  }

  /* Delete any auxdata allocations made by the VM */
  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
  assert( p->pAuxData==0 );
}

/*
** Clean up the VM after a single run.
*/
static void Cleanup(Vdbe *p){
65334
65335
65336
65337
65338
65339
65340

65341
65342
65343
65344
65345
65346
65347
        }else{
          /* We are forced to roll back the active transaction. Before doing
          ** so, abort any other statements this handle currently has active.
          */
          sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
          sqlite3CloseSavepoints(db);
          db->autoCommit = 1;

        }
      }
    }

    /* Check for immediate foreign key violations. */
    if( p->rc==SQLITE_OK ){
      sqlite3VdbeCheckFk(p, 0);







>







66329
66330
66331
66332
66333
66334
66335
66336
66337
66338
66339
66340
66341
66342
66343
        }else{
          /* We are forced to roll back the active transaction. Before doing
          ** so, abort any other statements this handle currently has active.
          */
          sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
          sqlite3CloseSavepoints(db);
          db->autoCommit = 1;
          p->nChange = 0;
        }
      }
    }

    /* Check for immediate foreign key violations. */
    if( p->rc==SQLITE_OK ){
      sqlite3VdbeCheckFk(p, 0);
65374
65375
65376
65377
65378
65379
65380

65381
65382
65383
65384
65385
65386
65387
65388

65389
65390
65391
65392
65393
65394
65395
65396
65397
65398
65399

65400
65401
65402
65403
65404
65405
65406
65407
65408
65409
65410
65411
65412
65413
65414
65415
65416
65417
65418
65419

65420
65421
65422
65423
65424
65425
65426
        }
        if( rc==SQLITE_BUSY && p->readOnly ){
          sqlite3VdbeLeave(p);
          return SQLITE_BUSY;
        }else if( rc!=SQLITE_OK ){
          p->rc = rc;
          sqlite3RollbackAll(db, SQLITE_OK);

        }else{
          db->nDeferredCons = 0;
          db->nDeferredImmCons = 0;
          db->flags &= ~SQLITE_DeferFKs;
          sqlite3CommitInternalChanges(db);
        }
      }else{
        sqlite3RollbackAll(db, SQLITE_OK);

      }
      db->nStatement = 0;
    }else if( eStatementOp==0 ){
      if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
        eStatementOp = SAVEPOINT_RELEASE;
      }else if( p->errorAction==OE_Abort ){
        eStatementOp = SAVEPOINT_ROLLBACK;
      }else{
        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
        sqlite3CloseSavepoints(db);
        db->autoCommit = 1;

      }
    }
  
    /* If eStatementOp is non-zero, then a statement transaction needs to
    ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
    ** do so. If this operation returns an error, and the current statement
    ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the
    ** current statement error code.
    */
    if( eStatementOp ){
      rc = sqlite3VdbeCloseStatement(p, eStatementOp);
      if( rc ){
        if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){
          p->rc = rc;
          sqlite3DbFree(db, p->zErrMsg);
          p->zErrMsg = 0;
        }
        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
        sqlite3CloseSavepoints(db);
        db->autoCommit = 1;

      }
    }
  
    /* If this was an INSERT, UPDATE or DELETE and no statement transaction
    ** has been rolled back, update the database connection change-counter. 
    */
    if( p->changeCntOn ){







>








>











>




















>







66370
66371
66372
66373
66374
66375
66376
66377
66378
66379
66380
66381
66382
66383
66384
66385
66386
66387
66388
66389
66390
66391
66392
66393
66394
66395
66396
66397
66398
66399
66400
66401
66402
66403
66404
66405
66406
66407
66408
66409
66410
66411
66412
66413
66414
66415
66416
66417
66418
66419
66420
66421
66422
66423
66424
66425
66426
        }
        if( rc==SQLITE_BUSY && p->readOnly ){
          sqlite3VdbeLeave(p);
          return SQLITE_BUSY;
        }else if( rc!=SQLITE_OK ){
          p->rc = rc;
          sqlite3RollbackAll(db, SQLITE_OK);
          p->nChange = 0;
        }else{
          db->nDeferredCons = 0;
          db->nDeferredImmCons = 0;
          db->flags &= ~SQLITE_DeferFKs;
          sqlite3CommitInternalChanges(db);
        }
      }else{
        sqlite3RollbackAll(db, SQLITE_OK);
        p->nChange = 0;
      }
      db->nStatement = 0;
    }else if( eStatementOp==0 ){
      if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
        eStatementOp = SAVEPOINT_RELEASE;
      }else if( p->errorAction==OE_Abort ){
        eStatementOp = SAVEPOINT_ROLLBACK;
      }else{
        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
        sqlite3CloseSavepoints(db);
        db->autoCommit = 1;
        p->nChange = 0;
      }
    }
  
    /* If eStatementOp is non-zero, then a statement transaction needs to
    ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
    ** do so. If this operation returns an error, and the current statement
    ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the
    ** current statement error code.
    */
    if( eStatementOp ){
      rc = sqlite3VdbeCloseStatement(p, eStatementOp);
      if( rc ){
        if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){
          p->rc = rc;
          sqlite3DbFree(db, p->zErrMsg);
          p->zErrMsg = 0;
        }
        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
        sqlite3CloseSavepoints(db);
        db->autoCommit = 1;
        p->nChange = 0;
      }
    }
  
    /* If this was an INSERT, UPDATE or DELETE and no statement transaction
    ** has been rolled back, update the database connection change-counter. 
    */
    if( p->changeCntOn ){
65674
65675
65676
65677
65678
65679
65680
65681

65682

65683
65684
65685
65686
65687
65688
65689
65690
    sqlite3DbFree(db, pSub);
  }
  for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  vdbeFreeOpArray(db, p->aOp, p->nOp);
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);
  sqlite3DbFree(db, p->pFree);
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)

  sqlite3DbFree(db, p->zExplain);

  sqlite3DbFree(db, p->pExplain);
#endif
}

/*
** Delete an entire VDBE.
*/
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){







|
>
|
>
|







66674
66675
66676
66677
66678
66679
66680
66681
66682
66683
66684
66685
66686
66687
66688
66689
66690
66691
66692
    sqlite3DbFree(db, pSub);
  }
  for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  vdbeFreeOpArray(db, p->aOp, p->nOp);
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);
  sqlite3DbFree(db, p->pFree);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  for(i=0; i<p->nScan; i++){
    sqlite3DbFree(db, p->aScan[i].zName);
  }
  sqlite3DbFree(db, p->aScan);
#endif
}

/*
** Delete an entire VDBE.
*/
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
65718
65719
65720
65721
65722
65723
65724
65725
65726
65727
65728
65729
65730
65731
65732
65733
65734
#ifdef SQLITE_TEST
  extern int sqlite3_search_count;
#endif
  assert( p->deferredMoveto );
  assert( p->isTable );
  rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
  if( rc ) return rc;
  p->lastRowid = p->movetoTarget;
  if( res!=0 ) return SQLITE_CORRUPT_BKPT;
  p->rowidIsValid = 1;
#ifdef SQLITE_TEST
  sqlite3_search_count++;
#endif
  p->deferredMoveto = 0;
  p->cacheStatus = CACHE_STALE;
  return SQLITE_OK;
}







<

<







66720
66721
66722
66723
66724
66725
66726

66727

66728
66729
66730
66731
66732
66733
66734
#ifdef SQLITE_TEST
  extern int sqlite3_search_count;
#endif
  assert( p->deferredMoveto );
  assert( p->isTable );
  rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
  if( rc ) return rc;

  if( res!=0 ) return SQLITE_CORRUPT_BKPT;

#ifdef SQLITE_TEST
  sqlite3_search_count++;
#endif
  p->deferredMoveto = 0;
  p->cacheStatus = CACHE_STALE;
  return SQLITE_OK;
}
65745
65746
65747
65748
65749
65750
65751











65752
65753
65754
65755
65756
65757
65758
65759
65760
65761
65762
65763
65764
65765
65766
65767
65768
65769
65770
65771
65772
65773
65774
65775
65776
65777
  assert( p->pCursor!=0 );
  assert( sqlite3BtreeCursorHasMoved(p->pCursor) );
  rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
  p->cacheStatus = CACHE_STALE;
  if( isDifferentRow ) p->nullRow = 1;
  return rc;
}












/*
** Make sure the cursor p is ready to read or write the row to which it
** was last positioned.  Return an error code if an OOM fault or I/O error
** prevents us from positioning the cursor to its correct position.
**
** If a MoveTo operation is pending on the given cursor, then do that
** MoveTo now.  If no move is pending, check to see if the row has been
** deleted out from under the cursor and if it has, mark the row as
** a NULL row.
**
** If the cursor is already pointing to the correct row and that row has
** not been deleted out from under the cursor, then this routine is a no-op.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
  if( p->deferredMoveto ){
    return handleDeferredMoveto(p);
  }
  if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
    return handleMovedCursor(p);
  }
  return SQLITE_OK;
}

/*
** The following functions:







>
>
>
>
>
>
>
>
>
>
>


















|







66745
66746
66747
66748
66749
66750
66751
66752
66753
66754
66755
66756
66757
66758
66759
66760
66761
66762
66763
66764
66765
66766
66767
66768
66769
66770
66771
66772
66773
66774
66775
66776
66777
66778
66779
66780
66781
66782
66783
66784
66785
66786
66787
66788
  assert( p->pCursor!=0 );
  assert( sqlite3BtreeCursorHasMoved(p->pCursor) );
  rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
  p->cacheStatus = CACHE_STALE;
  if( isDifferentRow ) p->nullRow = 1;
  return rc;
}

/*
** Check to ensure that the cursor is valid.  Restore the cursor
** if need be.  Return any I/O error from the restore operation.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
  if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
    return handleMovedCursor(p);
  }
  return SQLITE_OK;
}

/*
** Make sure the cursor p is ready to read or write the row to which it
** was last positioned.  Return an error code if an OOM fault or I/O error
** prevents us from positioning the cursor to its correct position.
**
** If a MoveTo operation is pending on the given cursor, then do that
** MoveTo now.  If no move is pending, check to see if the row has been
** deleted out from under the cursor and if it has, mark the row as
** a NULL row.
**
** If the cursor is already pointing to the correct row and that row has
** not been deleted out from under the cursor, then this routine is a no-op.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
  if( p->deferredMoveto ){
    return handleDeferredMoveto(p);
  }
  if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
    return handleMovedCursor(p);
  }
  return SQLITE_OK;
}

/*
** The following functions:
65827
65828
65829
65830
65831
65832
65833
65834
65835
65836
65837
65838
65839
65840
65841
65842
65843
  }
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
#   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
    i64 i = pMem->u.i;
    u64 u;
    if( i<0 ){
      if( i<(-MAX_6BYTE) ) return 6;
      /* Previous test prevents:  u = -(-9223372036854775808) */
      u = -i;
    }else{
      u = i;
    }
    if( u<=127 ){
      return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
    }
    if( u<=32767 ) return 2;







<
<
|







66838
66839
66840
66841
66842
66843
66844


66845
66846
66847
66848
66849
66850
66851
66852
  }
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
#   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
    i64 i = pMem->u.i;
    u64 u;
    if( i<0 ){


      u = ~i;
    }else{
      u = i;
    }
    if( u<=127 ){
      return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
    }
    if( u<=32767 ) return 2;
65995
65996
65997
65998
65999
66000
66001


66002
66003
66004
66005


66006
66007
66008
66009
66010
66011
66012
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
  u64 x = FOUR_BYTE_UINT(buf);
  u32 y = FOUR_BYTE_UINT(buf+4);
  x = (x<<32) + y;
  if( serial_type==6 ){


    pMem->u.i = *(i64*)&x;
    pMem->flags = MEM_Int;
    testcase( pMem->u.i<0 );
  }else{


#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
    /* Verify that integers and floating point values use the same
    ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
    ** defined that 64-bit floating point values really are mixed
    ** endian.
    */
    static const u64 t1 = ((u64)0x3ff00000)<<32;







>
>




>
>







67004
67005
67006
67007
67008
67009
67010
67011
67012
67013
67014
67015
67016
67017
67018
67019
67020
67021
67022
67023
67024
67025
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
  u64 x = FOUR_BYTE_UINT(buf);
  u32 y = FOUR_BYTE_UINT(buf+4);
  x = (x<<32) + y;
  if( serial_type==6 ){
    /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
    ** twos-complement integer. */
    pMem->u.i = *(i64*)&x;
    pMem->flags = MEM_Int;
    testcase( pMem->u.i<0 );
  }else{
    /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
    ** floating point number. */
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
    /* Verify that integers and floating point values use the same
    ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
    ** defined that 64-bit floating point values really are mixed
    ** endian.
    */
    static const u64 t1 = ((u64)0x3ff00000)<<32;
66026
66027
66028
66029
66030
66031
66032
66033

66034
66035
66036
66037


66038
66039
66040
66041
66042
66043


66044
66045
66046
66047
66048
66049


66050
66051
66052
66053
66054
66055


66056
66057
66058
66059
66060
66061


66062
66063
66064
66065
66066
66067
66068
66069
66070
66071
66072
66073
66074


66075
66076
66077
66078
66079




66080
66081
66082
66083
66084
66085
66086
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
  switch( serial_type ){
    case 10:   /* Reserved for future use */
    case 11:   /* Reserved for future use */
    case 0: {  /* NULL */

      pMem->flags = MEM_Null;
      break;
    }
    case 1: { /* 1-byte signed integer */


      pMem->u.i = ONE_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 1;
    }
    case 2: { /* 2-byte signed integer */


      pMem->u.i = TWO_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 2;
    }
    case 3: { /* 3-byte signed integer */


      pMem->u.i = THREE_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 3;
    }
    case 4: { /* 4-byte signed integer */


      pMem->u.i = FOUR_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 4;
    }
    case 5: { /* 6-byte signed integer */


      pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 6;
    }
    case 6:   /* 8-byte signed integer */
    case 7: { /* IEEE floating point */
      /* These use local variables, so do them in a separate routine
      ** to avoid having to move the frame pointer in the common case */
      return serialGet(buf,serial_type,pMem);
    }
    case 8:    /* Integer 0 */
    case 9: {  /* Integer 1 */


      pMem->u.i = serial_type-8;
      pMem->flags = MEM_Int;
      return 0;
    }
    default: {




      static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
      pMem->z = (char *)buf;
      pMem->n = (serial_type-12)/2;
      pMem->flags = aFlag[serial_type&1];
      return pMem->n;
    }
  }







|
>



|
>
>






>
>






>
>






>
>






>
>













>
>





>
>
>
>







67039
67040
67041
67042
67043
67044
67045
67046
67047
67048
67049
67050
67051
67052
67053
67054
67055
67056
67057
67058
67059
67060
67061
67062
67063
67064
67065
67066
67067
67068
67069
67070
67071
67072
67073
67074
67075
67076
67077
67078
67079
67080
67081
67082
67083
67084
67085
67086
67087
67088
67089
67090
67091
67092
67093
67094
67095
67096
67097
67098
67099
67100
67101
67102
67103
67104
67105
67106
67107
67108
67109
67110
67111
67112
67113
67114
67115
67116
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
  switch( serial_type ){
    case 10:   /* Reserved for future use */
    case 11:   /* Reserved for future use */
    case 0: {  /* Null */
      /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
      pMem->flags = MEM_Null;
      break;
    }
    case 1: {
      /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
      ** integer. */
      pMem->u.i = ONE_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 1;
    }
    case 2: { /* 2-byte signed integer */
      /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
      ** twos-complement integer. */
      pMem->u.i = TWO_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 2;
    }
    case 3: { /* 3-byte signed integer */
      /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
      ** twos-complement integer. */
      pMem->u.i = THREE_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 3;
    }
    case 4: { /* 4-byte signed integer */
      /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
      ** twos-complement integer. */
      pMem->u.i = FOUR_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 4;
    }
    case 5: { /* 6-byte signed integer */
      /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
      ** twos-complement integer. */
      pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
      pMem->flags = MEM_Int;
      testcase( pMem->u.i<0 );
      return 6;
    }
    case 6:   /* 8-byte signed integer */
    case 7: { /* IEEE floating point */
      /* These use local variables, so do them in a separate routine
      ** to avoid having to move the frame pointer in the common case */
      return serialGet(buf,serial_type,pMem);
    }
    case 8:    /* Integer 0 */
    case 9: {  /* Integer 1 */
      /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
      /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
      pMem->u.i = serial_type-8;
      pMem->flags = MEM_Int;
      return 0;
    }
    default: {
      /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
      ** length.
      ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
      ** (N-13)/2 bytes in length. */
      static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
      pMem->z = (char *)buf;
      pMem->n = (serial_type-12)/2;
      pMem->flags = aFlag[serial_type&1];
      return pMem->n;
    }
  }
67388
67389
67390
67391
67392
67393
67394

67395
67396
67397
67398
67399
67400
67401
  const char *z, 
  sqlite3_uint64 n,
  void (*xDel)(void *),
  unsigned char enc
){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  assert( xDel!=SQLITE_DYNAMIC );

  if( n>0x7fffffff ){
    (void)invokeValueDestructor(z, xDel, pCtx);
  }else{
    setResultStrOrError(pCtx, z, (int)n, enc, xDel);
  }
}
#ifndef SQLITE_OMIT_UTF16







>







68418
68419
68420
68421
68422
68423
68424
68425
68426
68427
68428
68429
68430
68431
68432
  const char *z, 
  sqlite3_uint64 n,
  void (*xDel)(void *),
  unsigned char enc
){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  assert( xDel!=SQLITE_DYNAMIC );
  if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
  if( n>0x7fffffff ){
    (void)invokeValueDestructor(z, xDel, pCtx);
  }else{
    setResultStrOrError(pCtx, z, (int)n, enc, xDel);
  }
}
#ifndef SQLITE_OMIT_UTF16
68035
68036
68037
68038
68039
68040
68041
68042
68043
68044
68045




68046




68047
68048
68049
68050
68051
68052
68053
*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){
  const void *ret = 0;
  Vdbe *p = (Vdbe *)pStmt;
  int n;
  sqlite3 *db = p->db;




  




  assert( db!=0 );
  n = sqlite3_column_count(pStmt);
  if( N<n && N>=0 ){
    N += useType*n;
    sqlite3_mutex_enter(db->mutex);
    assert( db->mallocFailed==0 );
    ret = xFunc(&p->aColName[N]);







|
|

|
>
>
>
>
|
>
>
>
>







69066
69067
69068
69069
69070
69071
69072
69073
69074
69075
69076
69077
69078
69079
69080
69081
69082
69083
69084
69085
69086
69087
69088
69089
69090
69091
69092
*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){
  const void *ret;
  Vdbe *p;
  int n;
  sqlite3 *db;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pStmt==0 ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  ret = 0;
  p = (Vdbe *)pStmt;
  db = p->db;
  assert( db!=0 );
  n = sqlite3_column_count(pStmt);
  if( N<n && N>=0 ){
    N += useType*n;
    sqlite3_mutex_enter(db->mutex);
    assert( db->mallocFailed==0 );
    ret = xFunc(&p->aColName[N]);
68504
68505
68506
68507
68508
68509
68510






68511
68512
68513
68514
68515
68516
68517
68518
68519
68520
68521
68522
68523
68524
68525







68526
68527
68528
68529
68530





































































68531
68532
68533
68534
68535
68536
68537
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb.  If pStmt is NULL, return the first
** prepared statement for the database connection.  Return NULL if there
** are no more.
*/
SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
  sqlite3_stmt *pNext;






  sqlite3_mutex_enter(pDb->mutex);
  if( pStmt==0 ){
    pNext = (sqlite3_stmt*)pDb->pVdbe;
  }else{
    pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext;
  }
  sqlite3_mutex_leave(pDb->mutex);
  return pNext;
}

/*
** Return the value of a status counter for a prepared statement
*/
SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
  Vdbe *pVdbe = (Vdbe*)pStmt;







  u32 v = pVdbe->aCounter[op];
  if( resetFlag ) pVdbe->aCounter[op] = 0;
  return (int)v;
}






































































/************** End of vdbeapi.c *********************************************/
/************** Begin file vdbetrace.c ***************************************/
/*
** 2009 November 25
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:







>
>
>
>
>
>















>
>
>
>
>
>
>
|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







69543
69544
69545
69546
69547
69548
69549
69550
69551
69552
69553
69554
69555
69556
69557
69558
69559
69560
69561
69562
69563
69564
69565
69566
69567
69568
69569
69570
69571
69572
69573
69574
69575
69576
69577
69578
69579
69580
69581
69582
69583
69584
69585
69586
69587
69588
69589
69590
69591
69592
69593
69594
69595
69596
69597
69598
69599
69600
69601
69602
69603
69604
69605
69606
69607
69608
69609
69610
69611
69612
69613
69614
69615
69616
69617
69618
69619
69620
69621
69622
69623
69624
69625
69626
69627
69628
69629
69630
69631
69632
69633
69634
69635
69636
69637
69638
69639
69640
69641
69642
69643
69644
69645
69646
69647
69648
69649
69650
69651
69652
69653
69654
69655
69656
69657
69658
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb.  If pStmt is NULL, return the first
** prepared statement for the database connection.  Return NULL if there
** are no more.
*/
SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
  sqlite3_stmt *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(pDb) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(pDb->mutex);
  if( pStmt==0 ){
    pNext = (sqlite3_stmt*)pDb->pVdbe;
  }else{
    pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext;
  }
  sqlite3_mutex_leave(pDb->mutex);
  return pNext;
}

/*
** Return the value of a status counter for a prepared statement
*/
SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
  Vdbe *pVdbe = (Vdbe*)pStmt;
  u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !pStmt ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  v = pVdbe->aCounter[op];
  if( resetFlag ) pVdbe->aCounter[op] = 0;
  return (int)v;
}

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Return status data for a single loop within query pStmt.
*/
SQLITE_API int sqlite3_stmt_scanstatus(
  sqlite3_stmt *pStmt,            /* Prepared statement being queried */
  int idx,                        /* Index of loop to report on */
  int iScanStatusOp,              /* Which metric to return */
  void *pOut                      /* OUT: Write the answer here */
){
  Vdbe *p = (Vdbe*)pStmt;
  ScanStatus *pScan;
  if( idx<0 || idx>=p->nScan ) return 1;
  pScan = &p->aScan[idx];
  switch( iScanStatusOp ){
    case SQLITE_SCANSTAT_NLOOP: {
      *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop];
      break;
    }
    case SQLITE_SCANSTAT_NVISIT: {
      *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit];
      break;
    }
    case SQLITE_SCANSTAT_EST: {
      double r = 1.0;
      LogEst x = pScan->nEst;
      while( x<100 ){
        x += 10;
        r *= 0.5;
      }
      *(double*)pOut = r*sqlite3LogEstToInt(x);
      break;
    }
    case SQLITE_SCANSTAT_NAME: {
      *(const char**)pOut = pScan->zName;
      break;
    }
    case SQLITE_SCANSTAT_EXPLAIN: {
      if( pScan->addrExplain ){
        *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z;
      }else{
        *(const char**)pOut = 0;
      }
      break;
    }
    case SQLITE_SCANSTAT_SELECTID: {
      if( pScan->addrExplain ){
        *(int*)pOut = p->aOp[ pScan->addrExplain ].p1;
      }else{
        *(int*)pOut = -1;
      }
      break;
    }
    default: {
      return 1;
    }
  }
  return 0;
}

/*
** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
*/
SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  memset(p->anExec, 0, p->nOp * sizeof(i64));
}
#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */

/************** End of vdbeapi.c *********************************************/
/************** Begin file vdbetrace.c ***************************************/
/*
** 2009 November 25
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
68710
68711
68712
68713
68714
68715
68716
68717
68718
68719
68720
68721
68722
68723
68724
68725
68726
68727
68728
68729
68730
68731
68732
68733
68734
68735
68736
68737
68738
68739
68740
68741
68742
68743
68744
68745
68746
68747
68748
68749
68750
68751
68752
68753
68754
68755
68756
68757
68758
68759
68760
68761
68762
68763
68764
68765
68766
68767
68768
68769
68770
68771
68772
68773
68774
68775
68776
68777
68778
68779
68780
68781
68782
68783
68784
68785
68786
68787
68788
68789
68790
68791
68792
68793
68794
68795
68796
68797
68798
68799
68800
68801
68802
68803
68804
68805
68806
68807
68808
68809
68810
68811
68812
68813
68814
68815
68816
68817
68818
68819
68820
68821
68822
68823
68824
68825
68826
68827
68828
68829
68830
68831
68832
68833
68834
68835
68836
68837
68838
    }
  }
  return sqlite3StrAccumFinish(&out);
}

#endif /* #ifndef SQLITE_OMIT_TRACE */

/*****************************************************************************
** The following code implements the data-structure explaining logic
** for the Vdbe.
*/

#if defined(SQLITE_ENABLE_TREE_EXPLAIN)

/*
** Allocate a new Explain object
*/
SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
  if( pVdbe ){
    Explain *p;
    sqlite3BeginBenignMalloc();
    p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
    if( p ){
      p->pVdbe = pVdbe;
      sqlite3_free(pVdbe->pExplain);
      pVdbe->pExplain = p;
      sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
                          SQLITE_MAX_LENGTH);
      p->str.useMalloc = 2;
    }else{
      sqlite3EndBenignMalloc();
    }
  }
}

/*
** Return true if the Explain ends with a new-line.
*/
static int endsWithNL(Explain *p){
  return p && p->str.zText && p->str.nChar
           && p->str.zText[p->str.nChar-1]=='\n';
}
    
/*
** Append text to the indentation
*/
SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
  Explain *p;
  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
    va_list ap;
    if( p->nIndent && endsWithNL(p) ){
      int n = p->nIndent;
      if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
      sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
    }   
    va_start(ap, zFormat);
    sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap);
    va_end(ap);
  }
}

/*
** Append a '\n' if there is not already one.
*/
SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe *pVdbe){
  Explain *p;
  if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
    sqlite3StrAccumAppend(&p->str, "\n", 1);
  }
}

/*
** Push a new indentation level.  Subsequent lines will be indented
** so that they begin at the current cursor position.
*/
SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe *pVdbe){
  Explain *p;
  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
    if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
      const char *z = p->str.zText;
      int i = p->str.nChar-1;
      int x;
      while( i>=0 && z[i]!='\n' ){ i--; }
      x = (p->str.nChar - 1) - i;
      if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
        x = p->aIndent[p->nIndent-1];
      }
      p->aIndent[p->nIndent] = x;
    }
    p->nIndent++;
  }
}

/*
** Pop the indentation stack by one level.
*/
SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe *p){
  if( p && p->pExplain ) p->pExplain->nIndent--;
}

/*
** Free the indentation structure
*/
SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe *pVdbe){
  if( pVdbe && pVdbe->pExplain ){
    sqlite3_free(pVdbe->zExplain);
    sqlite3ExplainNL(pVdbe);
    pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str);
    sqlite3_free(pVdbe->pExplain);
    pVdbe->pExplain = 0;
    sqlite3EndBenignMalloc();
  }
}

/*
** Return the explanation of a virtual machine.
*/
SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
  return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
}
#endif /* defined(SQLITE_DEBUG) */

/************** End of vdbetrace.c *******************************************/
/************** Begin file vdbe.c ********************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







69831
69832
69833
69834
69835
69836
69837



















































































































69838
69839
69840
69841
69842
69843
69844
    }
  }
  return sqlite3StrAccumFinish(&out);
}

#endif /* #ifndef SQLITE_OMIT_TRACE */




















































































































/************** End of vdbetrace.c *******************************************/
/************** Begin file vdbe.c ********************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
69041
69042
69043
69044
69045
69046
69047

69048
69049
69050
69051
69052
69053
69054
    p->apCsr[iCur] = 0;
  }
  if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
    p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
    memset(pCx, 0, sizeof(VdbeCursor));
    pCx->iDb = iDb;
    pCx->nField = nField;

    if( isBtreeCursor ){
      pCx->pCursor = (BtCursor*)
          &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
      sqlite3BtreeCursorZero(pCx->pCursor);
    }
  }
  return pCx;







>







70047
70048
70049
70050
70051
70052
70053
70054
70055
70056
70057
70058
70059
70060
70061
    p->apCsr[iCur] = 0;
  }
  if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
    p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
    memset(pCx, 0, sizeof(VdbeCursor));
    pCx->iDb = iDb;
    pCx->nField = nField;
    pCx->aOffset = &pCx->aType[nField];
    if( isBtreeCursor ){
      pCx->pCursor = (BtCursor*)
          &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
      sqlite3BtreeCursorZero(pCx->pCursor);
    }
  }
  return pCx;
69523
69524
69525
69526
69527
69528
69529



69530
69531
69532
69533
69534
69535
69536
    assert( pc>=0 && pc<p->nOp );
    if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    start = sqlite3Hwtime();
#endif
    nVmStep++;
    pOp = &aOp[pc];




    /* Only allow tracing if SQLITE_DEBUG is defined.
    */
#ifdef SQLITE_DEBUG
    if( db->flags & SQLITE_VdbeTrace ){
      sqlite3VdbePrintOp(stdout, pc, pOp);
    }







>
>
>







70530
70531
70532
70533
70534
70535
70536
70537
70538
70539
70540
70541
70542
70543
70544
70545
70546
    assert( pc>=0 && pc<p->nOp );
    if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    start = sqlite3Hwtime();
#endif
    nVmStep++;
    pOp = &aOp[pc];
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    if( p->anExec ) p->anExec[pc]++;
#endif

    /* Only allow tracing if SQLITE_DEBUG is defined.
    */
#ifdef SQLITE_DEBUG
    if( db->flags & SQLITE_VdbeTrace ){
      sqlite3VdbePrintOp(stdout, pc, pOp);
    }
70473
70474
70475
70476
70477
70478
70479
70480
70481
70482
70483
70484
70485
70486
70487
70488
70489
70490
70491
70492
70493
70494
70495
70496
70497
  }

  assert( pOp->p4type==P4_FUNCDEF );
  ctx.pFunc = pOp->p4.pFunc;
  ctx.iOp = pc;
  ctx.pVdbe = p;
  MemSetTypeFlag(ctx.pOut, MEM_Null);

  ctx.fErrorOrAux = 0;
  if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
    assert( pOp>aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = pOp[-1].p4.pColl;
  }
  db->lastRowid = lastRowid;
  (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
  lastRowid = db->lastRowid;

  /* If the function returned an error, throw an exception */
  if( ctx.fErrorOrAux ){
    if( ctx.isError ){
      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
      rc = ctx.isError;
    }







<

<
<
<
<
<
<


|







71483
71484
71485
71486
71487
71488
71489

71490






71491
71492
71493
71494
71495
71496
71497
71498
71499
71500
  }

  assert( pOp->p4type==P4_FUNCDEF );
  ctx.pFunc = pOp->p4.pFunc;
  ctx.iOp = pc;
  ctx.pVdbe = p;
  MemSetTypeFlag(ctx.pOut, MEM_Null);

  ctx.fErrorOrAux = 0;






  db->lastRowid = lastRowid;
  (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
  lastRowid = db->lastRowid;  /* Remember rowid changes made by xFunc */

  /* If the function returned an error, throw an exception */
  if( ctx.fErrorOrAux ){
    if( ctx.isError ){
      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
      rc = ctx.isError;
    }
71199
71200
71201
71202
71203
71204
71205
71206
71207
71208
71209
71210
71211
71212
71213
71214
71215
71216
71217
71218
71219
71220
71221
71222
71223
71224
71225
71226
71227
71228
71229
71230
71231
71232
71233
71234
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  pDest = &aMem[pOp->p3];
  memAboutToChange(p, pDest);
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( p2<pC->nField );
  aOffset = pC->aType + pC->nField;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
#endif
  pCrsr = pC->pCursor;
  assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
  assert( pCrsr!=0 || pC->nullRow );          /* pC->nullRow on PseudoTables */

  /* If the cursor cache is stale, bring it up-to-date */
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
    if( pC->nullRow ){
      if( pCrsr==0 ){
        assert( pC->pseudoTableReg>0 );
        pReg = &aMem[pC->pseudoTableReg];
        assert( pReg->flags & MEM_Blob );
        assert( memIsValid(pReg) );
        pC->payloadSize = pC->szRow = avail = pReg->n;
        pC->aRow = (u8*)pReg->z;
      }else{
        MemSetTypeFlag(pDest, MEM_Null);
        goto op_column_out;
      }
    }else{
      assert( pCrsr );
      if( pC->isTable==0 ){
        assert( sqlite3BtreeCursorIsValid(pCrsr) );
        VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);







|










|









|







72202
72203
72204
72205
72206
72207
72208
72209
72210
72211
72212
72213
72214
72215
72216
72217
72218
72219
72220
72221
72222
72223
72224
72225
72226
72227
72228
72229
72230
72231
72232
72233
72234
72235
72236
72237
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  pDest = &aMem[pOp->p3];
  memAboutToChange(p, pDest);
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( p2<pC->nField );
  aOffset = pC->aOffset;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
#endif
  pCrsr = pC->pCursor;
  assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
  assert( pCrsr!=0 || pC->nullRow );          /* pC->nullRow on PseudoTables */

  /* If the cursor cache is stale, bring it up-to-date */
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  if( pC->cacheStatus!=p->cacheCtr ){
    if( pC->nullRow ){
      if( pCrsr==0 ){
        assert( pC->pseudoTableReg>0 );
        pReg = &aMem[pC->pseudoTableReg];
        assert( pReg->flags & MEM_Blob );
        assert( memIsValid(pReg) );
        pC->payloadSize = pC->szRow = avail = pReg->n;
        pC->aRow = (u8*)pReg->z;
      }else{
        sqlite3VdbeMemSetNull(pDest);
        goto op_column_out;
      }
    }else{
      assert( pCrsr );
      if( pC->isTable==0 ){
        assert( sqlite3BtreeCursorIsValid(pCrsr) );
        VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
71255
71256
71257
71258
71259
71260
71261
71262
71263
71264
71265
71266
71267
71268
71269
71270
71271
71272
71273
71274
71275
71276
71277
71278
71279
71280
71281
71282
71283
















71284
71285
71286
71287
71288
71289
71290
71291
71292

71293
71294
71295
71296
71297
71298
71299
        goto too_big;
      }
    }
    pC->cacheStatus = p->cacheCtr;
    pC->iHdrOffset = getVarint32(pC->aRow, offset);
    pC->nHdrParsed = 0;
    aOffset[0] = offset;
    if( avail<offset ){
      /* pC->aRow does not have to hold the entire row, but it does at least
      ** need to cover the header of the record.  If pC->aRow does not contain
      ** the complete header, then set it to zero, forcing the header to be
      ** dynamically allocated. */
      pC->aRow = 0;
      pC->szRow = 0;
    }

    /* Make sure a corrupt database has not given us an oversize header.
    ** Do this now to avoid an oversize memory allocation.
    **
    ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
    ** types use so much data space that there can only be 4096 and 32 of
    ** them, respectively.  So the maximum header length results from a
    ** 3-byte type for each of the maximum of 32768 columns plus three
    ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
    */
    if( offset > 98307 || offset > pC->payloadSize ){
      rc = SQLITE_CORRUPT_BKPT;
      goto op_column_error;
    }
















  }

  /* Make sure at least the first p2+1 entries of the header have been
  ** parsed and valid information is in aOffset[] and pC->aType[].
  */
  if( pC->nHdrParsed<=p2 ){
    /* If there is more header available for parsing in the record, try
    ** to extract additional fields up through the p2+1-th field 
    */

    if( pC->iHdrOffset<aOffset[0] ){
      /* Make sure zData points to enough of the record to cover the header. */
      if( pC->aRow==0 ){
        memset(&sMem, 0, sizeof(sMem));
        rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], 
                                     !pC->isTable, &sMem);
        if( rc!=SQLITE_OK ){







<
<
<
<
<
<
<
<














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









>







72258
72259
72260
72261
72262
72263
72264








72265
72266
72267
72268
72269
72270
72271
72272
72273
72274
72275
72276
72277
72278
72279
72280
72281
72282
72283
72284
72285
72286
72287
72288
72289
72290
72291
72292
72293
72294
72295
72296
72297
72298
72299
72300
72301
72302
72303
72304
72305
72306
72307
72308
72309
72310
72311
        goto too_big;
      }
    }
    pC->cacheStatus = p->cacheCtr;
    pC->iHdrOffset = getVarint32(pC->aRow, offset);
    pC->nHdrParsed = 0;
    aOffset[0] = offset;









    /* Make sure a corrupt database has not given us an oversize header.
    ** Do this now to avoid an oversize memory allocation.
    **
    ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
    ** types use so much data space that there can only be 4096 and 32 of
    ** them, respectively.  So the maximum header length results from a
    ** 3-byte type for each of the maximum of 32768 columns plus three
    ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
    */
    if( offset > 98307 || offset > pC->payloadSize ){
      rc = SQLITE_CORRUPT_BKPT;
      goto op_column_error;
    }

    if( avail<offset ){
      /* pC->aRow does not have to hold the entire row, but it does at least
      ** need to cover the header of the record.  If pC->aRow does not contain
      ** the complete header, then set it to zero, forcing the header to be
      ** dynamically allocated. */
      pC->aRow = 0;
      pC->szRow = 0;
    }

    /* The following goto is an optimization.  It can be omitted and
    ** everything will still work.  But OP_Column is measurably faster
    ** by skipping the subsequent conditional, which is always true.
    */
    assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
    goto op_column_read_header;
  }

  /* Make sure at least the first p2+1 entries of the header have been
  ** parsed and valid information is in aOffset[] and pC->aType[].
  */
  if( pC->nHdrParsed<=p2 ){
    /* If there is more header available for parsing in the record, try
    ** to extract additional fields up through the p2+1-th field 
    */
    op_column_read_header:
    if( pC->iHdrOffset<aOffset[0] ){
      /* Make sure zData points to enough of the record to cover the header. */
      if( pC->aRow==0 ){
        memset(&sMem, 0, sizeof(sMem));
        rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], 
                                     !pC->isTable, &sMem);
        if( rc!=SQLITE_OK ){
71330
71331
71332
71333
71334
71335
71336
71337
71338



71339
71340
71341

71342
71343
71344
71345
71346
71347
71348
71349
71350
71351
71352
71353
71354
71355
71356
71357
71358
71359
71360
71361
71362
71363
71364
71365
71366
71367
      pC->nHdrParsed = i;
      pC->iHdrOffset = (u32)(zHdr - zData);
      if( pC->aRow==0 ){
        sqlite3VdbeMemRelease(&sMem);
        sMem.flags = MEM_Null;
      }
  
      /* If we have read more header data than was contained in the header,
      ** or if the end of the last field appears to be past the end of the



      ** record, or if the end of the last field appears to be before the end
      ** of the record (when all fields present), then we must be dealing 
      ** with a corrupt database.

      */
      if( (zHdr > zEndHdr)
       || (offset > pC->payloadSize)
       || (zHdr==zEndHdr && offset!=pC->payloadSize)
      ){
        rc = SQLITE_CORRUPT_BKPT;
        goto op_column_error;
      }
    }

    /* If after trying to extra new entries from the header, nHdrParsed is
    ** still not up to p2, that means that the record has fewer than p2
    ** columns.  So the result will be either the default value or a NULL.
    */
    if( pC->nHdrParsed<=p2 ){
      if( pOp->p4type==P4_MEM ){
        sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
      }else{
        MemSetTypeFlag(pDest, MEM_Null);
      }
      goto op_column_out;
    }
  }

  /* Extract the content for the p2+1-th column.  Control can only
  ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are







|
|
>
>
>
|
<
<
>

|

<














|







72342
72343
72344
72345
72346
72347
72348
72349
72350
72351
72352
72353
72354


72355
72356
72357
72358

72359
72360
72361
72362
72363
72364
72365
72366
72367
72368
72369
72370
72371
72372
72373
72374
72375
72376
72377
72378
72379
72380
      pC->nHdrParsed = i;
      pC->iHdrOffset = (u32)(zHdr - zData);
      if( pC->aRow==0 ){
        sqlite3VdbeMemRelease(&sMem);
        sMem.flags = MEM_Null;
      }
  
      /* The record is corrupt if any of the following are true:
      ** (1) the bytes of the header extend past the declared header size
      **          (zHdr>zEndHdr)
      ** (2) the entire header was used but not all data was used
      **          (zHdr==zEndHdr && offset!=pC->payloadSize)
      ** (3) the end of the data extends beyond the end of the record.


      **          (offset > pC->payloadSize)
      */
      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
       || (offset > pC->payloadSize)

      ){
        rc = SQLITE_CORRUPT_BKPT;
        goto op_column_error;
      }
    }

    /* If after trying to extra new entries from the header, nHdrParsed is
    ** still not up to p2, that means that the record has fewer than p2
    ** columns.  So the result will be either the default value or a NULL.
    */
    if( pC->nHdrParsed<=p2 ){
      if( pOp->p4type==P4_MEM ){
        sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
      }else{
        sqlite3VdbeMemSetNull(pDest);
      }
      goto op_column_out;
    }
  }

  /* Extract the content for the p2+1-th column.  Control can only
  ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
71529
71530
71531
71532
71533
71534
71535
71536
71537
71538
71539
71540
71541
71542
71543
71544
71545
71546
71547
71548
71549
71550
71551


71552

71553
71554
71555
71556
71557
71558
71559

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  pRec = pLast;
  do{
    assert( memIsValid(pRec) );
    serial_type = sqlite3VdbeSerialType(pRec, file_format);
    len = sqlite3VdbeSerialTypeLen(serial_type);
    if( pRec->flags & MEM_Zero ){
      if( nData ){
        sqlite3VdbeMemExpandBlob(pRec);
      }else{
        nZero += pRec->u.nZero;
        len -= pRec->u.nZero;
      }
    }
    nData += len;
    testcase( serial_type==127 );
    testcase( serial_type==128 );
    nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
  }while( (--pRec)>=pData0 );



  /* Add the initial header varint and total the size */

  testcase( nHdr==126 );
  testcase( nHdr==127 );
  if( nHdr<=126 ){
    /* The common case */
    nHdr += 1;
  }else{
    /* Rare case of a really large header */







|















>
>
|
>







72542
72543
72544
72545
72546
72547
72548
72549
72550
72551
72552
72553
72554
72555
72556
72557
72558
72559
72560
72561
72562
72563
72564
72565
72566
72567
72568
72569
72570
72571
72572
72573
72574
72575

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  pRec = pLast;
  do{
    assert( memIsValid(pRec) );
    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
    len = sqlite3VdbeSerialTypeLen(serial_type);
    if( pRec->flags & MEM_Zero ){
      if( nData ){
        sqlite3VdbeMemExpandBlob(pRec);
      }else{
        nZero += pRec->u.nZero;
        len -= pRec->u.nZero;
      }
    }
    nData += len;
    testcase( serial_type==127 );
    testcase( serial_type==128 );
    nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
  }while( (--pRec)>=pData0 );

  /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
  ** which determines the total number of bytes in the header. The varint
  ** value is the size of the header in bytes including the size varint
  ** itself. */
  testcase( nHdr==126 );
  testcase( nHdr==127 );
  if( nHdr<=126 ){
    /* The common case */
    nHdr += 1;
  }else{
    /* Rare case of a really large header */
71578
71579
71580
71581
71582
71583
71584
71585


71586


71587
71588
71589
71590
71591
71592
71593

  /* Write the record */
  i = putVarint32(zNewRecord, nHdr);
  j = nHdr;
  assert( pData0<=pLast );
  pRec = pData0;
  do{
    serial_type = sqlite3VdbeSerialType(pRec, file_format);


    i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */


    j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
  }while( (++pRec)<=pLast );
  assert( i==nHdr );
  assert( j==nByte );

  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  pOut->n = (int)nByte;







|
>
>

>
>







72594
72595
72596
72597
72598
72599
72600
72601
72602
72603
72604
72605
72606
72607
72608
72609
72610
72611
72612
72613

  /* Write the record */
  i = putVarint32(zNewRecord, nHdr);
  j = nHdr;
  assert( pData0<=pLast );
  pRec = pData0;
  do{
    serial_type = pRec->uTemp;
    /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
    ** additional varints, one per column. */
    i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */
    /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
    ** immediately follow the header. */
    j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
  }while( (++pRec)<=pLast );
  assert( i==nHdr );
  assert( j==nByte );

  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  pOut->n = (int)nByte;
71734
71735
71736
71737
71738
71739
71740

71741
71742

71743
71744



71745


71746
71747
71748
71749
71750
71751
71752
71753
71754
71755
71756
71757
71758
71759
71760
          db->autoCommit = 0;
          p->rc = rc = SQLITE_BUSY;
          goto vdbe_return;
        }
        db->isTransactionSavepoint = 0;
        rc = p->rc;
      }else{

        iSavepoint = db->nSavepoint - iSavepoint - 1;
        if( p1==SAVEPOINT_ROLLBACK ){

          for(ii=0; ii<db->nDb; ii++){
            sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);



          }


        }
        for(ii=0; ii<db->nDb; ii++){
          rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
          if( rc!=SQLITE_OK ){
            goto abort_due_to_error;
          }
        }
        if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
          sqlite3ExpirePreparedStatements(db);
          sqlite3ResetAllSchemasOfConnection(db);
          db->flags = (db->flags | SQLITE_InternChanges);
        }
      }
  
      /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all 







>


>

|
>
>
>

>
>







|







72754
72755
72756
72757
72758
72759
72760
72761
72762
72763
72764
72765
72766
72767
72768
72769
72770
72771
72772
72773
72774
72775
72776
72777
72778
72779
72780
72781
72782
72783
72784
72785
72786
72787
          db->autoCommit = 0;
          p->rc = rc = SQLITE_BUSY;
          goto vdbe_return;
        }
        db->isTransactionSavepoint = 0;
        rc = p->rc;
      }else{
        int isSchemaChange;
        iSavepoint = db->nSavepoint - iSavepoint - 1;
        if( p1==SAVEPOINT_ROLLBACK ){
          isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
          for(ii=0; ii<db->nDb; ii++){
            rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
                                       SQLITE_ABORT_ROLLBACK,
                                       isSchemaChange==0);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;
          }
        }else{
          isSchemaChange = 0;
        }
        for(ii=0; ii<db->nDb; ii++){
          rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
          if( rc!=SQLITE_OK ){
            goto abort_due_to_error;
          }
        }
        if( isSchemaChange ){
          sqlite3ExpirePreparedStatements(db);
          sqlite3ResetAllSchemasOfConnection(db);
          db->flags = (db->flags | SQLITE_InternChanges);
        }
      }
  
      /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all 
72143
72144
72145
72146
72147
72148
72149
72150
72151
72152
72153
72154
72155
72156
72157
  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
  assert( p->bIsReader );
  assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
          || p->readOnly==0 );

  if( p->expired ){
    rc = SQLITE_ABORT;
    break;
  }

  nField = 0;
  pKeyInfo = 0;
  p2 = pOp->p2;
  iDb = pOp->p3;







|







73170
73171
73172
73173
73174
73175
73176
73177
73178
73179
73180
73181
73182
73183
73184
  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
  assert( p->bIsReader );
  assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
          || p->readOnly==0 );

  if( p->expired ){
    rc = SQLITE_ABORT_ROLLBACK;
    break;
  }

  nField = 0;
  pKeyInfo = 0;
  p2 = pOp->p2;
  iDb = pOp->p3;
72203
72204
72205
72206
72207
72208
72209
72210
72211
72212
72213
72214
72215
72216
72217
72218
72219
72220
  pCur->isOrdered = 1;
  pCur->pgnoRoot = p2;
  rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
  pCur->pKeyInfo = pKeyInfo;
  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
  sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));

  /* Since it performs no memory allocation or IO, the only value that
  ** sqlite3BtreeCursor() may return is SQLITE_OK. */
  assert( rc==SQLITE_OK );

  /* Set the VdbeCursor.isTable variable. Previous versions of
  ** SQLite used to check if the root-page flags were sane at this point
  ** and report database corruption if they were not, but this check has
  ** since moved into the btree layer.  */  
  pCur->isTable = pOp->p4type!=P4_KEYINFO;
  break;
}







<
<
<
<







73230
73231
73232
73233
73234
73235
73236




73237
73238
73239
73240
73241
73242
73243
  pCur->isOrdered = 1;
  pCur->pgnoRoot = p2;
  rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
  pCur->pKeyInfo = pKeyInfo;
  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
  sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));





  /* Set the VdbeCursor.isTable variable. Previous versions of
  ** SQLite used to check if the root-page flags were sane at this point
  ** and report database corruption if they were not, but this check has
  ** since moved into the btree layer.  */  
  pCur->isTable = pOp->p4type!=P4_KEYINFO;
  break;
}
72481
72482
72483
72484
72485
72486
72487
72488
72489
72490
72491
72492
72493
72494
72495
    ** blob, or NULL.  But it needs to be an integer before we can do
    ** the seek, so convert it. */
    pIn3 = &aMem[pOp->p3];
    if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
      applyNumericAffinity(pIn3, 0);
    }
    iKey = sqlite3VdbeIntValue(pIn3);
    pC->rowidIsValid = 0;

    /* If the P3 value could not be converted into an integer without
    ** loss of information, then special processing is required... */
    if( (pIn3->flags & MEM_Int)==0 ){
      if( (pIn3->flags & MEM_Real)==0 ){
        /* If the P3 value cannot be converted into any kind of a number,
        ** then the seek is not possible, so jump to P2 */







<







73504
73505
73506
73507
73508
73509
73510

73511
73512
73513
73514
73515
73516
73517
    ** blob, or NULL.  But it needs to be an integer before we can do
    ** the seek, so convert it. */
    pIn3 = &aMem[pOp->p3];
    if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
      applyNumericAffinity(pIn3, 0);
    }
    iKey = sqlite3VdbeIntValue(pIn3);


    /* If the P3 value could not be converted into an integer without
    ** loss of information, then special processing is required... */
    if( (pIn3->flags & MEM_Int)==0 ){
      if( (pIn3->flags & MEM_Real)==0 ){
        /* If the P3 value cannot be converted into any kind of a number,
        ** then the seek is not possible, so jump to P2 */
72517
72518
72519
72520
72521
72522
72523

72524
72525
72526
72527
72528
72529
72530
72531
72532
72533
72534
72535
72536
72537
        assert( OP_SeekLE==(OP_SeekLT+1) );
        assert( OP_SeekGT==(OP_SeekGE+1) );
        assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
        if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
      }
    } 
    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);

    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    if( res==0 ){
      pC->rowidIsValid = 1;
      pC->lastRowid = iKey;
    }
  }else{
    nField = pOp->p4.i;
    assert( pOp->p4type==P4_INT32 );
    assert( nField>0 );
    r.pKeyInfo = pC->pKeyInfo;
    r.nField = (u16)nField;








>



<
<
<
<







73539
73540
73541
73542
73543
73544
73545
73546
73547
73548
73549




73550
73551
73552
73553
73554
73555
73556
        assert( OP_SeekLE==(OP_SeekLT+1) );
        assert( OP_SeekGT==(OP_SeekGE+1) );
        assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
        if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
      }
    } 
    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
    pC->movetoTarget = iKey;  /* Used by OP_Delete */
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }




  }else{
    nField = pOp->p4.i;
    assert( pOp->p4type==P4_INT32 );
    assert( nField>0 );
    r.pKeyInfo = pC->pKeyInfo;
    r.nField = (u16)nField;

72553
72554
72555
72556
72557
72558
72559
72560
72561
72562
72563
72564
72565
72566
72567
72568
72569
72570
72571
72572
72573
72574
72575
72576
72577
72578
72579
72580
72581
72582
72583
72584
72585
72586
72587
72588
72589
    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
    ExpandBlob(r.aMem);
    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    pC->rowidIsValid = 0;
  }
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
  sqlite3_search_count++;
#endif
  if( oc>=OP_SeekGE ){  assert( oc==OP_SeekGE || oc==OP_SeekGT );
    if( res<0 || (res==0 && oc==OP_SeekGT) ){
      res = 0;
      rc = sqlite3BtreeNext(pC->pCursor, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      pC->rowidIsValid = 0;
    }else{
      res = 0;
    }
  }else{
    assert( oc==OP_SeekLT || oc==OP_SeekLE );
    if( res>0 || (res==0 && oc==OP_SeekLT) ){
      res = 0;
      rc = sqlite3BtreePrevious(pC->pCursor, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      pC->rowidIsValid = 0;
    }else{
      /* res might be negative because the table is empty.  Check to
      ** see if this is the case.
      */
      res = sqlite3BtreeEof(pC->pCursor);
    }
  }







<











<









<







73572
73573
73574
73575
73576
73577
73578

73579
73580
73581
73582
73583
73584
73585
73586
73587
73588
73589

73590
73591
73592
73593
73594
73595
73596
73597
73598

73599
73600
73601
73602
73603
73604
73605
    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
    ExpandBlob(r.aMem);
    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }

  }
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
  sqlite3_search_count++;
#endif
  if( oc>=OP_SeekGE ){  assert( oc==OP_SeekGE || oc==OP_SeekGT );
    if( res<0 || (res==0 && oc==OP_SeekGT) ){
      res = 0;
      rc = sqlite3BtreeNext(pC->pCursor, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;

    }else{
      res = 0;
    }
  }else{
    assert( oc==OP_SeekLT || oc==OP_SeekLE );
    if( res>0 || (res==0 && oc==OP_SeekLT) ){
      res = 0;
      rc = sqlite3BtreePrevious(pC->pCursor, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;

    }else{
      /* res might be negative because the table is empty.  Check to
      ** see if this is the case.
      */
      res = sqlite3BtreeEof(pC->pCursor);
    }
  }
72612
72613
72614
72615
72616
72617
72618
72619
72620
72621
72622
72623
72624
72625
72626
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pCursor!=0 );
  assert( pC->isTable );
  pC->nullRow = 0;
  pIn2 = &aMem[pOp->p2];
  pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
  pC->rowidIsValid = 0;
  pC->deferredMoveto = 1;
  break;
}
  

/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]







<







73628
73629
73630
73631
73632
73633
73634

73635
73636
73637
73638
73639
73640
73641
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pCursor!=0 );
  assert( pC->isTable );
  pC->nullRow = 0;
  pIn2 = &aMem[pOp->p2];
  pC->movetoTarget = sqlite3VdbeIntValue(pIn2);

  pC->deferredMoveto = 1;
  break;
}
  

/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
72719
72720
72721
72722
72723
72724
72725
72726
72727
72728
72729
72730
72731
72732
72733
72734
72735
72736
      if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
#endif
    }
    pIdxKey = &r;
  }else{
    pIdxKey = sqlite3VdbeAllocUnpackedRecord(
        pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
    ); 
    if( pIdxKey==0 ) goto no_mem;
    assert( pIn3->flags & MEM_Blob );
    assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */
    sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
  }
  pIdxKey->default_rc = 0;
  if( pOp->opcode==OP_NoConflict ){
    /* For the OP_NoConflict opcode, take the jump if any of the
    ** input fields are NULL, since any key with a NULL will not
    ** conflict */







|


|







73734
73735
73736
73737
73738
73739
73740
73741
73742
73743
73744
73745
73746
73747
73748
73749
73750
73751
      if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
#endif
    }
    pIdxKey = &r;
  }else{
    pIdxKey = sqlite3VdbeAllocUnpackedRecord(
        pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
    );
    if( pIdxKey==0 ) goto no_mem;
    assert( pIn3->flags & MEM_Blob );
    ExpandBlob(pIn3);
    sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
  }
  pIdxKey->default_rc = 0;
  if( pOp->opcode==OP_NoConflict ){
    /* For the OP_NoConflict opcode, take the jump if any of the
    ** input fields are NULL, since any key with a NULL will not
    ** conflict */
72798
72799
72800
72801
72802
72803
72804
72805
72806
72807
72808
72809
72810
72811
72812
72813
72814
72815
72816
72817
72818
72819
72820
  assert( pC->isTable );
  assert( pC->pseudoTableReg==0 );
  pCrsr = pC->pCursor;
  assert( pCrsr!=0 );
  res = 0;
  iKey = pIn3->u.i;
  rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
  pC->lastRowid = pIn3->u.i;
  pC->rowidIsValid = res==0 ?1:0;
  pC->nullRow = 0;
  pC->cacheStatus = CACHE_STALE;
  pC->deferredMoveto = 0;
  VdbeBranchTaken(res!=0,2);
  if( res!=0 ){
    pc = pOp->p2 - 1;
    assert( pC->rowidIsValid==0 );
  }
  pC->seekResult = res;
  break;
}

/* Opcode: Sequence P1 P2 * * *
** Synopsis: r[P2]=cursor[P1].ctr++







|
<






<







73813
73814
73815
73816
73817
73818
73819
73820

73821
73822
73823
73824
73825
73826

73827
73828
73829
73830
73831
73832
73833
  assert( pC->isTable );
  assert( pC->pseudoTableReg==0 );
  pCrsr = pC->pCursor;
  assert( pCrsr!=0 );
  res = 0;
  iKey = pIn3->u.i;
  rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
  pC->movetoTarget = iKey;  /* Used by OP_Delete */

  pC->nullRow = 0;
  pC->cacheStatus = CACHE_STALE;
  pC->deferredMoveto = 0;
  VdbeBranchTaken(res!=0,2);
  if( res!=0 ){
    pc = pOp->p2 - 1;

  }
  pC->seekResult = res;
  break;
}

/* Opcode: Sequence P1 P2 * * *
** Synopsis: r[P2]=cursor[P1].ctr++
72940
72941
72942
72943
72944
72945
72946
72947
72948
72949
72950
72951



72952
72953
72954
72955
72956
72957
72958
72959
72960
72961
72962
72963
72964
72965
72966
72967
72968
72969
72970
72971
72972
72973
72974
72975
72976
72977
72978
72979
    if( pC->useRandomRowid ){
      /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the
      ** largest possible integer (9223372036854775807) then the database
      ** engine starts picking positive candidate ROWIDs at random until
      ** it finds one that is not previously used. */
      assert( pOp->p3==0 );  /* We cannot be in random rowid mode if this is
                             ** an AUTOINCREMENT table. */
      /* on the first attempt, simply do one more than previous */
      v = lastRowid;
      v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
      v++; /* ensure non-zero */
      cnt = 0;



      while(   ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
                                                 0, &res))==SQLITE_OK)
            && (res==0)
            && (++cnt<100)){
        /* collision - try another random rowid */
        sqlite3_randomness(sizeof(v), &v);
        if( cnt<5 ){
          /* try "small" random rowids for the initial attempts */
          v &= 0xffffff;
        }else{
          v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
        }
        v++; /* ensure non-zero */
      }
      if( rc==SQLITE_OK && res==0 ){
        rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
        goto abort_due_to_error;
      }
      assert( v>0 );  /* EV: R-40812-03570 */
    }
    pC->rowidIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }
  pOut->u.i = v;
  break;
}








<
<
<
<

>
>
>
|


|
<
<
<
<
<
<
<
<
<
<






<







73953
73954
73955
73956
73957
73958
73959




73960
73961
73962
73963
73964
73965
73966
73967










73968
73969
73970
73971
73972
73973

73974
73975
73976
73977
73978
73979
73980
    if( pC->useRandomRowid ){
      /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the
      ** largest possible integer (9223372036854775807) then the database
      ** engine starts picking positive candidate ROWIDs at random until
      ** it finds one that is not previously used. */
      assert( pOp->p3==0 );  /* We cannot be in random rowid mode if this is
                             ** an AUTOINCREMENT table. */




      cnt = 0;
      do{
        sqlite3_randomness(sizeof(v), &v);
        v &= (MAX_ROWID>>1); v++;  /* Ensure that v is greater than zero */
      }while(  ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
                                                 0, &res))==SQLITE_OK)
            && (res==0)
            && (++cnt<100));










      if( rc==SQLITE_OK && res==0 ){
        rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
        goto abort_due_to_error;
      }
      assert( v>0 );  /* EV: R-40812-03570 */
    }

    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }
  pOut->u.i = v;
  break;
}

73070
73071
73072
73073
73074
73075
73076
73077
73078
73079
73080
73081
73082
73083
73084
  }else{
    nZero = 0;
  }
  rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                          pData->z, pData->n, nZero,
                          (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
  );
  pC->rowidIsValid = 0;
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
    zDb = db->aDb[pC->iDb].zName;
    zTbl = pOp->p4.z;







<







74071
74072
74073
74074
74075
74076
74077

74078
74079
74080
74081
74082
74083
74084
  }else{
    nZero = 0;
  }
  rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                          pData->z, pData->n, nZero,
                          (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
  );

  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
    zDb = db->aDb[pC->iDb].zName;
    zTbl = pOp->p4.z;
73107
73108
73109
73110
73111
73112
73113
73114
73115
73116
73117
73118
73119
73120
73121
73122
73123
73124
73125
73126
73127
73128
73129

73130
73131

73132
73133
73134
73135
73136
73137
73138
73139
73140
73141
73142
73143
73144
73145
73146
73147
**
** If P4 is not NULL, then it is the name of the table that P1 is
** pointing to.  The update hook will be invoked, if it exists.
** If P4 is not NULL then the P1 cursor must have been positioned
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {
  i64 iKey;
  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
  iKey = pC->lastRowid;      /* Only used for the update hook */

  /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
  ** OP_Column on the same table without any intervening operations that
  ** might move or invalidate the cursor.  Hence cursor pC is always pointing
  ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
  ** below is always a no-op and cannot fail.  We will run it anyhow, though,
  ** to guard against future changes to the code generator.
  **/

  assert( pC->deferredMoveto==0 );
  rc = sqlite3VdbeCursorMoveto(pC);

  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;

  rc = sqlite3BtreeDelete(pC->pCursor);
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
                        db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
    assert( pC->iDb>=0 );
  }
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}
/* Opcode: ResetCount * * * * *
**







<






|

|
|
|
|
|
|
<
>
|
<
>
|
|






|







74107
74108
74109
74110
74111
74112
74113

74114
74115
74116
74117
74118
74119
74120
74121
74122
74123
74124
74125
74126
74127

74128
74129

74130
74131
74132
74133
74134
74135
74136
74137
74138
74139
74140
74141
74142
74143
74144
74145
74146
**
** If P4 is not NULL, then it is the name of the table that P1 is
** pointing to.  The update hook will be invoked, if it exists.
** If P4 is not NULL then the P1 cursor must have been positioned
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {

  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
  assert( pC->deferredMoveto==0 );

#ifdef SQLITE_DEBUG
  /* The seek operation that positioned the cursor prior to OP_Delete will
  ** have also set the pC->movetoTarget field to the rowid of the row that
  ** is being deleted */
  if( pOp->p4.z && pC->isTable ){
    i64 iKey = 0;

    sqlite3BtreeKeySize(pC->pCursor, &iKey);
    assert( pC->movetoTarget==iKey ); 

  }
#endif
 
  rc = sqlite3BtreeDelete(pC->pCursor);
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
                        db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
    assert( pC->iDb>=0 );
  }
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}
/* Opcode: ResetCount * * * * *
**
73186
73187
73188
73189
73190
73191
73192
73193
73194
73195
73196







73197
73198
73199
73200
73201
73202
73203
73204
73205


73206
73207
73208
73209
73210
73211
73212
  VdbeBranchTaken(res!=0,2);
  if( res ){
    pc = pOp->p2-1;
  }
  break;
};

/* Opcode: SorterData P1 P2 * * *
** Synopsis: r[P2]=data
**
** Write into register P2 the current sorter data for sorter cursor P1.







*/
case OP_SorterData: {
  VdbeCursor *pC;

  pOut = &aMem[pOp->p2];
  pC = p->apCsr[pOp->p1];
  assert( isSorter(pC) );
  rc = sqlite3VdbeSorterRowkey(pC, pOut);
  assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );


  break;
}

/* Opcode: RowData P1 P2 * * *
** Synopsis: r[P2]=data
**
** Write into register P2 the complete row data for cursor P1.







|



>
>
>
>
>
>
>









>
>







74185
74186
74187
74188
74189
74190
74191
74192
74193
74194
74195
74196
74197
74198
74199
74200
74201
74202
74203
74204
74205
74206
74207
74208
74209
74210
74211
74212
74213
74214
74215
74216
74217
74218
74219
74220
  VdbeBranchTaken(res!=0,2);
  if( res ){
    pc = pOp->p2-1;
  }
  break;
};

/* Opcode: SorterData P1 P2 P3 * *
** Synopsis: r[P2]=data
**
** Write into register P2 the current sorter data for sorter cursor P1.
** Then clear the column header cache on cursor P3.
**
** This opcode is normally use to move a record out of the sorter and into
** a register that is the source for a pseudo-table cursor created using
** OpenPseudo.  That pseudo-table cursor is the one that is identified by
** parameter P3.  Clearing the P3 column cache as part of this opcode saves
** us from having to issue a separate NullRow instruction to clear that cache.
*/
case OP_SorterData: {
  VdbeCursor *pC;

  pOut = &aMem[pOp->p2];
  pC = p->apCsr[pOp->p1];
  assert( isSorter(pC) );
  rc = sqlite3VdbeSorterRowkey(pC, pOut);
  assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
  break;
}

/* Opcode: RowData P1 P2 * * *
** Synopsis: r[P2]=data
**
** Write into register P2 the complete row data for cursor P1.
73245
73246
73247
73248
73249
73250
73251
73252
73253
73254
73255



73256
73257
73258
73259


73260
73261

73262
73263
73264
73265
73266
73267
73268
73269
73270
73271
73272
73273
73274
73275
73276
73277

73278
73279
73280
73281
73282
73283
73284
73285
  assert( pC->isTable || pOp->opcode!=OP_RowData );
  assert( pC->isTable==0 || pOp->opcode==OP_RowData );
  assert( pC!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTableReg==0 );
  assert( pC->pCursor!=0 );
  pCrsr = pC->pCursor;
  assert( sqlite3BtreeCursorIsValid(pCrsr) );

  /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
  ** OP_Rewind/Op_Next with no intervening instructions that might invalidate



  ** the cursor.  Hence the following sqlite3VdbeCursorMoveto() call is always
  ** a no-op and can never fail.  But we leave it in place as a safety.
  */
  assert( pC->deferredMoveto==0 );


  rc = sqlite3VdbeCursorMoveto(pC);
  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;


  if( pC->isTable==0 ){
    assert( !pC->isTable );
    VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
    assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
    if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
    n = (u32)n64;
  }else{
    VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
    assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
    if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
  }

  if( sqlite3VdbeMemClearAndResize(pOut, n) ){
    goto no_mem;
  }
  pOut->n = n;
  MemSetTypeFlag(pOut, MEM_Blob);
  if( pC->isTable==0 ){
    rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
  }else{







<



>
>
>
|
<


>
>

|
>
















>
|







74253
74254
74255
74256
74257
74258
74259

74260
74261
74262
74263
74264
74265
74266

74267
74268
74269
74270
74271
74272
74273
74274
74275
74276
74277
74278
74279
74280
74281
74282
74283
74284
74285
74286
74287
74288
74289
74290
74291
74292
74293
74294
74295
74296
74297
74298
  assert( pC->isTable || pOp->opcode!=OP_RowData );
  assert( pC->isTable==0 || pOp->opcode==OP_RowData );
  assert( pC!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTableReg==0 );
  assert( pC->pCursor!=0 );
  pCrsr = pC->pCursor;


  /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
  ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
  ** the cursor.  If this where not the case, on of the following assert()s
  ** would fail.  Should this ever change (because of changes in the code
  ** generator) then the fix would be to insert a call to
  ** sqlite3VdbeCursorMoveto().

  */
  assert( pC->deferredMoveto==0 );
  assert( sqlite3BtreeCursorIsValid(pCrsr) );
#if 0  /* Not required due to the previous to assert() statements */
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
#endif

  if( pC->isTable==0 ){
    assert( !pC->isTable );
    VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
    assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
    if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
    n = (u32)n64;
  }else{
    VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
    assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
    if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
  }
  testcase( n==0 );
  if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
    goto no_mem;
  }
  pOut->n = n;
  MemSetTypeFlag(pOut, MEM_Blob);
  if( pC->isTable==0 ){
    rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
  }else{
73322
73323
73324
73325
73326
73327
73328
73329
73330
73331
73332
73333

73334
73335
73336
73337
73338
73339
73340
73341
73342
73343
73344
73345
73346
73347
73348
73349
73350
73351
73352
73353
73354
73355
73356
73357
73358
73359
73360
73361
73362
    pModule = pVtab->pModule;
    assert( pModule->xRowid );
    rc = pModule->xRowid(pC->pVtabCursor, &v);
    sqlite3VtabImportErrmsg(p, pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{
    assert( pC->pCursor!=0 );
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->rowidIsValid ){
      v = pC->lastRowid;
    }else{

      rc = sqlite3BtreeKeySize(pC->pCursor, &v);
      assert( rc==SQLITE_OK );  /* Always so because of CursorMoveto() above */
    }
  }
  pOut->u.i = v;
  break;
}

/* Opcode: NullRow P1 * * * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always
** write a NULL.
*/
case OP_NullRow: {
  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  pC->nullRow = 1;
  pC->rowidIsValid = 0;
  pC->cacheStatus = CACHE_STALE;
  if( pC->pCursor ){
    sqlite3BtreeClearCursor(pC->pCursor);
  }
  break;
}








|

|
|
|
>
|
|
<


















<







74335
74336
74337
74338
74339
74340
74341
74342
74343
74344
74345
74346
74347
74348
74349

74350
74351
74352
74353
74354
74355
74356
74357
74358
74359
74360
74361
74362
74363
74364
74365
74366
74367

74368
74369
74370
74371
74372
74373
74374
    pModule = pVtab->pModule;
    assert( pModule->xRowid );
    rc = pModule->xRowid(pC->pVtabCursor, &v);
    sqlite3VtabImportErrmsg(p, pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{
    assert( pC->pCursor!=0 );
    rc = sqlite3VdbeCursorRestore(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->nullRow ){
      pOut->flags = MEM_Null;
      break;
    }
    rc = sqlite3BtreeKeySize(pC->pCursor, &v);
    assert( rc==SQLITE_OK );  /* Always so because of CursorRestore() above */

  }
  pOut->u.i = v;
  break;
}

/* Opcode: NullRow P1 * * * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always
** write a NULL.
*/
case OP_NullRow: {
  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  pC->nullRow = 1;

  pC->cacheStatus = CACHE_STALE;
  if( pC->pCursor ){
    sqlite3BtreeClearCursor(pC->pCursor);
  }
  break;
}

73382
73383
73384
73385
73386
73387
73388
73389
73390
73391
73392
73393
73394
73395
73396
  assert( pC!=0 );
  pCrsr = pC->pCursor;
  res = 0;
  assert( pCrsr!=0 );
  rc = sqlite3BtreeLast(pCrsr, &res);
  pC->nullRow = (u8)res;
  pC->deferredMoveto = 0;
  pC->rowidIsValid = 0;
  pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_DEBUG
  pC->seekOp = OP_Last;
#endif
  if( pOp->p2>0 ){
    VdbeBranchTaken(res!=0,2);
    if( res ) pc = pOp->p2 - 1;







<







74394
74395
74396
74397
74398
74399
74400

74401
74402
74403
74404
74405
74406
74407
  assert( pC!=0 );
  pCrsr = pC->pCursor;
  res = 0;
  assert( pCrsr!=0 );
  rc = sqlite3BtreeLast(pCrsr, &res);
  pC->nullRow = (u8)res;
  pC->deferredMoveto = 0;

  pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_DEBUG
  pC->seekOp = OP_Last;
#endif
  if( pOp->p2>0 ){
    VdbeBranchTaken(res!=0,2);
    if( res ) pc = pOp->p2 - 1;
73420
73421
73422
73423
73424
73425
73426
73427
73428
73429
73430
73431
73432
73433
73434
73435
73436
  p->aCounter[SQLITE_STMTSTATUS_SORT]++;
  /* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end.  In other words, the cursor is
** configured to use Next, not Prev.
*/
case OP_Rewind: {        /* jump */
  VdbeCursor *pC;







|
|
|







74431
74432
74433
74434
74435
74436
74437
74438
74439
74440
74441
74442
74443
74444
74445
74446
74447
  p->aCounter[SQLITE_STMTSTATUS_SORT]++;
  /* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty, jump immediately to P2.
** If the table or index is not empty, fall through to the following 
** instruction.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end.  In other words, the cursor is
** configured to use Next, not Prev.
*/
case OP_Rewind: {        /* jump */
  VdbeCursor *pC;
73449
73450
73451
73452
73453
73454
73455
73456
73457
73458
73459
73460
73461
73462
73463
    rc = sqlite3VdbeSorterRewind(pC, &res);
  }else{
    pCrsr = pC->pCursor;
    assert( pCrsr );
    rc = sqlite3BtreeFirst(pCrsr, &res);
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
    pC->rowidIsValid = 0;
  }
  pC->nullRow = (u8)res;
  assert( pOp->p2>0 && pOp->p2<p->nOp );
  VdbeBranchTaken(res!=0,2);
  if( res ){
    pc = pOp->p2 - 1;
  }







<







74460
74461
74462
74463
74464
74465
74466

74467
74468
74469
74470
74471
74472
74473
    rc = sqlite3VdbeSorterRewind(pC, &res);
  }else{
    pCrsr = pC->pCursor;
    assert( pCrsr );
    rc = sqlite3BtreeFirst(pCrsr, &res);
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;

  }
  pC->nullRow = (u8)res;
  assert( pOp->p2>0 && pOp->p2<p->nOp );
  VdbeBranchTaken(res!=0,2);
  if( res ){
    pc = pOp->p2 - 1;
  }
73575
73576
73577
73578
73579
73580
73581
73582
73583
73584
73585
73586
73587
73588
73589
    p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
  }else{
    pC->nullRow = 1;
  }
  pC->rowidIsValid = 0;
  goto check_for_interrupt;
}

/* Opcode: IdxInsert P1 P2 P3 * P5
** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the







<







74585
74586
74587
74588
74589
74590
74591

74592
74593
74594
74595
74596
74597
74598
    p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
  }else{
    pC->nullRow = 1;
  }

  goto check_for_interrupt;
}

/* Opcode: IdxInsert P1 P2 P3 * P5
** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
73691
73692
73693
73694
73695
73696
73697







73698
73699
73700
73701
73702
73703
73704
73705
73706
73707
73708

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  pCrsr = pC->pCursor;
  assert( pCrsr!=0 );
  pOut->flags = MEM_Null;







  rc = sqlite3VdbeCursorMoveto(pC);
  if( NEVER(rc) ) goto abort_due_to_error;
  assert( pC->deferredMoveto==0 );
  assert( pC->isTable==0 );
  if( !pC->nullRow ){
    rowid = 0;  /* Not needed.  Only used to silence a warning. */
    rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    pOut->u.i = rowid;







>
>
>
>
>
>
>
|
|
|
<







74700
74701
74702
74703
74704
74705
74706
74707
74708
74709
74710
74711
74712
74713
74714
74715
74716

74717
74718
74719
74720
74721
74722
74723

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  pCrsr = pC->pCursor;
  assert( pCrsr!=0 );
  pOut->flags = MEM_Null;
  assert( pC->isTable==0 );
  assert( pC->deferredMoveto==0 );

  /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
  ** out from under the cursor.  That will never happend for an IdxRowid
  ** opcode, hence the NEVER() arround the check of the return value.
  */
  rc = sqlite3VdbeCursorRestore(pC);
  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;


  if( !pC->nullRow ){
    rowid = 0;  /* Not needed.  Only used to silence a warning. */
    rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    pOut->u.i = rowid;
74334
74335
74336
74337
74338
74339
74340



74341
74342
74343
74344
74345
74346
74347
74348
74349
74350
74351
74352
74353
74354
74355
74356
74357

74358
74359
74360
74361
74362
74363
74364
74365
74366
74367



74368
74369
74370
74371
74372
74373
74374
    pFrame->apCsr = p->apCsr;
    pFrame->nCursor = p->nCursor;
    pFrame->aOp = p->aOp;
    pFrame->nOp = p->nOp;
    pFrame->token = pProgram->token;
    pFrame->aOnceFlag = p->aOnceFlag;
    pFrame->nOnceFlag = p->nOnceFlag;




    pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
    for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
      pMem->flags = MEM_Undefined;
      pMem->db = db;
    }
  }else{
    pFrame = pRt->u.pFrame;
    assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
    assert( pProgram->nCsr==pFrame->nChildCsr );
    assert( pc==pFrame->pc );
  }

  p->nFrame++;
  pFrame->pParent = p->pFrame;
  pFrame->lastRowid = lastRowid;
  pFrame->nChange = p->nChange;

  p->nChange = 0;
  p->pFrame = pFrame;
  p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
  p->nMem = pFrame->nChildMem;
  p->nCursor = (u16)pFrame->nChildCsr;
  p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
  p->aOp = aOp = pProgram->aOp;
  p->nOp = pProgram->nOp;
  p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
  p->nOnceFlag = pProgram->nOnce;



  pc = -1;
  memset(p->aOnceFlag, 0, p->nOnceFlag);

  break;
}

/* Opcode: Param P1 P2 * * *







>
>
>

















>










>
>
>







75349
75350
75351
75352
75353
75354
75355
75356
75357
75358
75359
75360
75361
75362
75363
75364
75365
75366
75367
75368
75369
75370
75371
75372
75373
75374
75375
75376
75377
75378
75379
75380
75381
75382
75383
75384
75385
75386
75387
75388
75389
75390
75391
75392
75393
75394
75395
75396
    pFrame->apCsr = p->apCsr;
    pFrame->nCursor = p->nCursor;
    pFrame->aOp = p->aOp;
    pFrame->nOp = p->nOp;
    pFrame->token = pProgram->token;
    pFrame->aOnceFlag = p->aOnceFlag;
    pFrame->nOnceFlag = p->nOnceFlag;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    pFrame->anExec = p->anExec;
#endif

    pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
    for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
      pMem->flags = MEM_Undefined;
      pMem->db = db;
    }
  }else{
    pFrame = pRt->u.pFrame;
    assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
    assert( pProgram->nCsr==pFrame->nChildCsr );
    assert( pc==pFrame->pc );
  }

  p->nFrame++;
  pFrame->pParent = p->pFrame;
  pFrame->lastRowid = lastRowid;
  pFrame->nChange = p->nChange;
  pFrame->nDbChange = p->db->nChange;
  p->nChange = 0;
  p->pFrame = pFrame;
  p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
  p->nMem = pFrame->nChildMem;
  p->nCursor = (u16)pFrame->nChildCsr;
  p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
  p->aOp = aOp = pProgram->aOp;
  p->nOp = pProgram->nOp;
  p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
  p->nOnceFlag = pProgram->nOnce;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  p->anExec = 0;
#endif
  pc = -1;
  memset(p->aOnceFlag, 0, p->nOnceFlag);

  break;
}

/* Opcode: Param P1 P2 * * *
74554
74555
74556
74557
74558
74559
74560
74561

74562
74563
74564
74565
74566
74567
74568
74569
74570
74571
74572
74573
74574
74575
  ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  ctx.pMem = pMem = &aMem[pOp->p3];
  pMem->n++;
  sqlite3VdbeMemInit(&t, db, MEM_Null);
  ctx.pOut = &t;
  ctx.isError = 0;
  ctx.pColl = 0;

  ctx.skipFlag = 0;
  if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = pOp[-1].p4.pColl;
  }
  (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
  if( ctx.isError ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
    rc = ctx.isError;
  }
  if( ctx.skipFlag ){
    assert( pOp[-1].opcode==OP_CollSeq );







|
>

<
<
<
<
<
<







75576
75577
75578
75579
75580
75581
75582
75583
75584
75585






75586
75587
75588
75589
75590
75591
75592
  ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  ctx.pMem = pMem = &aMem[pOp->p3];
  pMem->n++;
  sqlite3VdbeMemInit(&t, db, MEM_Null);
  ctx.pOut = &t;
  ctx.isError = 0;
  ctx.pVdbe = p;
  ctx.iOp = pc;
  ctx.skipFlag = 0;






  (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
  if( ctx.isError ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
    rc = ctx.isError;
  }
  if( ctx.skipFlag ){
    assert( pOp[-1].opcode==OP_CollSeq );
75554
75555
75556
75557
75558
75559
75560





75561
75562
75563
75564
75565
75566
75567

  int rc = SQLITE_OK;
  char *zErr = 0;
  Table *pTab;
  Parse *pParse = 0;
  Incrblob *pBlob = 0;






  flags = !!flags;                /* flags = (flags ? 1 : 0); */
  *ppBlob = 0;

  sqlite3_mutex_enter(db->mutex);

  pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
  if( !pBlob ) goto blob_open_out;







>
>
>
>
>







76571
76572
76573
76574
76575
76576
76577
76578
76579
76580
76581
76582
76583
76584
76585
76586
76587
76588
76589

  int rc = SQLITE_OK;
  char *zErr = 0;
  Table *pTab;
  Parse *pParse = 0;
  Incrblob *pBlob = 0;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || ppBlob==0 || zTable==0 ){
    return SQLITE_MISUSE_BKPT;
  }
#endif
  flags = !!flags;                /* flags = (flags ? 1 : 0); */
  *ppBlob = 0;

  sqlite3_mutex_enter(db->mutex);

  pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
  if( !pBlob ) goto blob_open_out;
75772
75773
75774
75775
75776
75777
75778
75779
75780
75781
75782
75783
75784
75785
75786
75787
75788
75789
75790
75791
75792
75793
75794
75795
75796
75797
75798
75799
75800

75801
75802
75803
75804
75805
75806
75807
  db = p->db;
  sqlite3_mutex_enter(db->mutex);
  v = (Vdbe*)p->pStmt;

  if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
    /* Request is out of range. Return a transient error. */
    rc = SQLITE_ERROR;
    sqlite3Error(db, SQLITE_ERROR);
  }else if( v==0 ){
    /* If there is no statement handle, then the blob-handle has
    ** already been invalidated. Return SQLITE_ABORT in this case.
    */
    rc = SQLITE_ABORT;
  }else{
    /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
    ** returned, clean-up the statement handle.
    */
    assert( db == v->db );
    sqlite3BtreeEnterCursor(p->pCsr);
    rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
    sqlite3BtreeLeaveCursor(p->pCsr);
    if( rc==SQLITE_ABORT ){
      sqlite3VdbeFinalize(v);
      p->pStmt = 0;
    }else{
      db->errCode = rc;
      v->rc = rc;
    }
  }

  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

/*
** Read data from a blob handle.







<

















<



>







76794
76795
76796
76797
76798
76799
76800

76801
76802
76803
76804
76805
76806
76807
76808
76809
76810
76811
76812
76813
76814
76815
76816
76817

76818
76819
76820
76821
76822
76823
76824
76825
76826
76827
76828
  db = p->db;
  sqlite3_mutex_enter(db->mutex);
  v = (Vdbe*)p->pStmt;

  if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
    /* Request is out of range. Return a transient error. */
    rc = SQLITE_ERROR;

  }else if( v==0 ){
    /* If there is no statement handle, then the blob-handle has
    ** already been invalidated. Return SQLITE_ABORT in this case.
    */
    rc = SQLITE_ABORT;
  }else{
    /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
    ** returned, clean-up the statement handle.
    */
    assert( db == v->db );
    sqlite3BtreeEnterCursor(p->pCsr);
    rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
    sqlite3BtreeLeaveCursor(p->pCsr);
    if( rc==SQLITE_ABORT ){
      sqlite3VdbeFinalize(v);
      p->pStmt = 0;
    }else{

      v->rc = rc;
    }
  }
  sqlite3Error(db, rc);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

/*
** Read data from a blob handle.
75970
75971
75972
75973
75974
75975
75976
75977
75978
75979
75980
75981
75982
75983
75984
** calling thread usually launches a worker thread to do so. Except, if
** there are already N worker threads running, the main thread does the work
** itself.
**
** The sorter is running in multi-threaded mode if (a) the library was built
** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
** than zero, and (b) worker threads have been enabled at runtime by calling
** sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, ...).
**
** When Rewind() is called, any data remaining in memory is flushed to a 
** final PMA. So at this point the data is stored in some number of sorted
** PMAs within temporary files on disk.
**
** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
** sorter is running in single-threaded mode, then these PMAs are merged







|







76991
76992
76993
76994
76995
76996
76997
76998
76999
77000
77001
77002
77003
77004
77005
** calling thread usually launches a worker thread to do so. Except, if
** there are already N worker threads running, the main thread does the work
** itself.
**
** The sorter is running in multi-threaded mode if (a) the library was built
** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
** than zero, and (b) worker threads have been enabled at runtime by calling
** "PRAGMA threads=N" with some value of N greater than 0.
**
** When Rewind() is called, any data remaining in memory is flushed to a 
** final PMA. So at this point the data is stored in some number of sorted
** PMAs within temporary files on disk.
**
** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
** sorter is running in single-threaded mode, then these PMAs are merged
76015
76016
76017
76018
76019
76020
76021







76022
76023
76024
76025
76026
76027
76028
** messages to stderr that may be helpful in understanding the performance
** characteristics of the sorter in multi-threaded mode.
*/
#if 0
# define SQLITE_DEBUG_SORTER_THREADS 1
#endif








/*
** Private objects used by the sorter
*/
typedef struct MergeEngine MergeEngine;     /* Merge PMAs together */
typedef struct PmaReader PmaReader;         /* Incrementally read one PMA */
typedef struct PmaWriter PmaWriter;         /* Incrementally write one PMA */
typedef struct SorterRecord SorterRecord;   /* A record being sorted */







>
>
>
>
>
>
>







77036
77037
77038
77039
77040
77041
77042
77043
77044
77045
77046
77047
77048
77049
77050
77051
77052
77053
77054
77055
77056
** messages to stderr that may be helpful in understanding the performance
** characteristics of the sorter in multi-threaded mode.
*/
#if 0
# define SQLITE_DEBUG_SORTER_THREADS 1
#endif

/*
** Hard-coded maximum amount of data to accumulate in memory before flushing
** to a level 0 PMA. The purpose of this limit is to prevent various integer
** overflows. 512MiB.
*/
#define SQLITE_MAX_MXPMASIZE    (1<<29)

/*
** Private objects used by the sorter
*/
typedef struct MergeEngine MergeEngine;     /* Merge PMAs together */
typedef struct PmaReader PmaReader;         /* Incrementally read one PMA */
typedef struct PmaWriter PmaWriter;         /* Incrementally write one PMA */
typedef struct SorterRecord SorterRecord;   /* A record being sorted */
76713
76714
76715
76716
76717
76718
76719
76720
76721
76722
76723
76724
76725
76726
76727
76728
76729
76730
76731
76732
76733
      pTask->pSorter = pSorter;
    }

    if( !sqlite3TempInMemory(db) ){
      pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
      mxCache = db->aDb[0].pSchema->cache_size;
      if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
      pSorter->mxPmaSize = mxCache * pgsz;

      /* If the application has not configure scratch memory using
      ** SQLITE_CONFIG_SCRATCH then we assume it is OK to do large memory
      ** allocations.  If scratch memory has been configured, then assume
      ** large memory allocations should be avoided to prevent heap
      ** fragmentation.
      */
      if( sqlite3GlobalConfig.pScratch==0 ){
        assert( pSorter->iMemory==0 );
        pSorter->nMemory = pgsz;
        pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
      }







|

|
|
<
|
<







77741
77742
77743
77744
77745
77746
77747
77748
77749
77750
77751

77752

77753
77754
77755
77756
77757
77758
77759
      pTask->pSorter = pSorter;
    }

    if( !sqlite3TempInMemory(db) ){
      pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
      mxCache = db->aDb[0].pSchema->cache_size;
      if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);

      /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
      ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary

      ** large heap allocations.

      */
      if( sqlite3GlobalConfig.pScratch==0 ){
        assert( pSorter->iMemory==0 );
        pSorter->nMemory = pgsz;
        pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
      }
78160
78161
78162
78163
78164
78165
78166
78167
78168
78169
78170
78171
78172
78173
78174

  rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
  if( rc==SQLITE_OK ){
#if SQLITE_MAX_WORKER_THREADS
    assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
    if( pSorter->bUseThreads ){
      int iTask;
      PmaReader *pReadr;
      SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
      rc = vdbeSortAllocUnpacked(pLast);
      if( rc==SQLITE_OK ){
        pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
        pSorter->pReader = pReadr;
        if( pReadr==0 ) rc = SQLITE_NOMEM;
      }







|







79186
79187
79188
79189
79190
79191
79192
79193
79194
79195
79196
79197
79198
79199
79200

  rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
  if( rc==SQLITE_OK ){
#if SQLITE_MAX_WORKER_THREADS
    assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
    if( pSorter->bUseThreads ){
      int iTask;
      PmaReader *pReadr = 0;
      SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
      rc = vdbeSortAllocUnpacked(pLast);
      if( rc==SQLITE_OK ){
        pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
        pSorter->pReader = pReadr;
        if( pReadr==0 ) rc = SQLITE_NOMEM;
      }
79091
79092
79093
79094
79095
79096
79097
79098
79099
79100
79101
79102
79103
79104
79105
79106
79107
79108
79109
79110
79111
79112
79113
** This needs to occur when copying a TK_AGG_FUNCTION node from an
** outer query into an inner subquery.
**
** incrAggFunctionDepth(pExpr,n) is the main routine.  incrAggDepth(..)
** is a helper function - a callback for the tree walker.
*/
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i;
  return WRC_Continue;
}
static void incrAggFunctionDepth(Expr *pExpr, int N){
  if( N>0 ){
    Walker w;
    memset(&w, 0, sizeof(w));
    w.xExprCallback = incrAggDepth;
    w.u.i = N;
    sqlite3WalkExpr(&w, pExpr);
  }
}

/*
** Turn the pExpr expression into an alias for the iCol-th column of the
** result set in pEList.







|







|







80117
80118
80119
80120
80121
80122
80123
80124
80125
80126
80127
80128
80129
80130
80131
80132
80133
80134
80135
80136
80137
80138
80139
** This needs to occur when copying a TK_AGG_FUNCTION node from an
** outer query into an inner subquery.
**
** incrAggFunctionDepth(pExpr,n) is the main routine.  incrAggDepth(..)
** is a helper function - a callback for the tree walker.
*/
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
  return WRC_Continue;
}
static void incrAggFunctionDepth(Expr *pExpr, int N){
  if( N>0 ){
    Walker w;
    memset(&w, 0, sizeof(w));
    w.xExprCallback = incrAggDepth;
    w.u.n = N;
    sqlite3WalkExpr(&w, pExpr);
  }
}

/*
** Turn the pExpr expression into an alias for the iCol-th column of the
** result set in pEList.
79647
79648
79649
79650
79651
79652
79653
79654
79655
79656
79657
79658
79659
79660
79661
*/
static int exprProbability(Expr *p){
  double r = -1.0;
  if( p->op!=TK_FLOAT ) return -1;
  sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
  assert( r>=0.0 );
  if( r>1.0 ) return -1;
  return (int)(r*1000.0);
}

/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree.  Return 0 to continue the search down







|







80673
80674
80675
80676
80677
80678
80679
80680
80681
80682
80683
80684
80685
80686
80687
*/
static int exprProbability(Expr *p){
  double r = -1.0;
  if( p->op!=TK_FLOAT ) return -1;
  sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
  assert( r>=0.0 );
  if( r>1.0 ) return -1;
  return (int)(r*134217728.0);
}

/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree.  Return 0 to continue the search down
79779
79780
79781
79782
79783
79784
79785
79786
79787
79788
79789
79790
79791
79792
79793
            ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
            ** likelihood(X,0.0625).
            ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
            ** likelihood(X,0.9375).
            ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
            ** likelihood(X,0.9375). */
            /* TUNING: unlikely() probability is 0.0625.  likely() is 0.9375 */
            pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
          }             
        }
#ifndef SQLITE_OMIT_AUTHORIZATION
        auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
        if( auth!=SQLITE_OK ){
          if( auth==SQLITE_DENY ){
            sqlite3ErrorMsg(pParse, "not authorized to use function: %s",







|







80805
80806
80807
80808
80809
80810
80811
80812
80813
80814
80815
80816
80817
80818
80819
            ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
            ** likelihood(X,0.0625).
            ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
            ** likelihood(X,0.9375).
            ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
            ** likelihood(X,0.9375). */
            /* TUNING: unlikely() probability is 0.0625.  likely() is 0.9375 */
            pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
          }             
        }
#ifndef SQLITE_OMIT_AUTHORIZATION
        auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
        if( auth!=SQLITE_OK ){
          if( auth==SQLITE_DENY ){
            sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
81595
81596
81597
81598
81599
81600
81601

81602
81603
81604
81605
81606
81607
81608
  pNew->iLimit = 0;
  pNew->iOffset = 0;
  pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
  pNew->addrOpenEphm[0] = -1;
  pNew->addrOpenEphm[1] = -1;
  pNew->nSelectRow = p->nSelectRow;
  pNew->pWith = withDup(db, p->pWith);

  return pNew;
}
#else
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
  assert( p==0 );
  return 0;
}







>







82621
82622
82623
82624
82625
82626
82627
82628
82629
82630
82631
82632
82633
82634
82635
  pNew->iLimit = 0;
  pNew->iOffset = 0;
  pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
  pNew->addrOpenEphm[0] = -1;
  pNew->addrOpenEphm[1] = -1;
  pNew->nSelectRow = p->nSelectRow;
  pNew->pWith = withDup(db, p->pWith);
  sqlite3SelectSetName(pNew, p->zSelName);
  return pNew;
}
#else
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
  assert( p==0 );
  return 0;
}
81735
81736
81737
81738
81739
81740
81741
81742
81743
81744
81745
81746
81747
81748
81749
81750

81751
81752











81753
81754
81755
81756
81757
81758
81759
81760
81761
81762
81763
81764
81765
81766
81767
81768
81769
81770



81771
81772
81773
81774
81775
81776
81777
81778
81779
81780



81781
81782














81783
81784
81785
81786
81787
81788
81789
81790
81791
81792
81793
81794
81795
81796
81797
81798
81799

81800
81801
81802
81803
81804
81805
81806
81807
81808
81809
81810
81811
81812
81813
81814
81815
81816
81817
81818
81819
81820
81821
81822
81823
81824
81825
81826
81827










81828
81829
81830
81831
81832
81833
81834
81835

81836
81837
81838
81839
81840
81841
81842
81843
    sqlite3DbFree(db, pItem->zSpan);
  }
  sqlite3DbFree(db, pList->a);
  sqlite3DbFree(db, pList);
}

/*
** These routines are Walker callbacks.  Walker.u.pi is a pointer
** to an integer.  These routines are checking an expression to see
** if it is a constant.  Set *Walker.u.pi to 0 if the expression is
** not constant.
**
** These callback routines are used to implement the following:
**
**     sqlite3ExprIsConstant()
**     sqlite3ExprIsConstantNotJoin()

**     sqlite3ExprIsConstantOrFunction()
**











*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){

  /* If pWalker->u.i is 3 then any term of the expression that comes from
  ** the ON or USING clauses of a join disqualifies the expression
  ** from being considered constant. */
  if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){
    pWalker->u.i = 0;
    return WRC_Abort;
  }

  switch( pExpr->op ){
    /* Consider functions to be constant if all their arguments are constant
    ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST
    ** flag. */
    case TK_FUNCTION:
      if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){
        return WRC_Continue;



      }
      /* Fall through */
    case TK_ID:
    case TK_COLUMN:
    case TK_AGG_FUNCTION:
    case TK_AGG_COLUMN:
      testcase( pExpr->op==TK_ID );
      testcase( pExpr->op==TK_COLUMN );
      testcase( pExpr->op==TK_AGG_FUNCTION );
      testcase( pExpr->op==TK_AGG_COLUMN );



      pWalker->u.i = 0;
      return WRC_Abort;














    default:
      testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
      testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
      return WRC_Continue;
  }
}
static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  pWalker->u.i = 0;
  return WRC_Abort;
}
static int exprIsConst(Expr *p, int initFlag){
  Walker w;
  memset(&w, 0, sizeof(w));
  w.u.i = initFlag;
  w.xExprCallback = exprNodeIsConstant;
  w.xSelectCallback = selectNodeIsConstant;

  sqlite3WalkExpr(&w, p);
  return w.u.i;
}

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
  return exprIsConst(p, 1);
}

/*
** Walk an expression tree.  Return 1 if the expression is constant
** that does no originate from the ON or USING clauses of a join.
** Return 0 if it involves variables or function calls or terms from
** an ON or USING clause.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
  return exprIsConst(p, 3);
}

/*
** Walk an expression tree.  Return 1 if the expression is constant










** or a function call with constant arguments.  Return and 0 if there
** are any variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){

  return exprIsConst(p, 2);
}

/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.







|
|
|
|



|
|
>
|

>
>
>
>
>
>
>
>
>
>
>



|
|

|
|





|
|

|

>
>
>

<








>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|


|


|


>

|



|







|



|





|



|
>
>
>
>
>
>
>
>
>
>







|
>
|







82762
82763
82764
82765
82766
82767
82768
82769
82770
82771
82772
82773
82774
82775
82776
82777
82778
82779
82780
82781
82782
82783
82784
82785
82786
82787
82788
82789
82790
82791
82792
82793
82794
82795
82796
82797
82798
82799
82800
82801
82802
82803
82804
82805
82806
82807
82808
82809
82810
82811
82812
82813

82814
82815
82816
82817
82818
82819
82820
82821
82822
82823
82824
82825
82826
82827
82828
82829
82830
82831
82832
82833
82834
82835
82836
82837
82838
82839
82840
82841
82842
82843
82844
82845
82846
82847
82848
82849
82850
82851
82852
82853
82854
82855
82856
82857
82858
82859
82860
82861
82862
82863
82864
82865
82866
82867
82868
82869
82870
82871
82872
82873
82874
82875
82876
82877
82878
82879
82880
82881
82882
82883
82884
82885
82886
82887
82888
82889
82890
82891
82892
82893
82894
82895
82896
82897
82898
82899
82900
82901
82902
82903
82904
82905
82906
82907
82908
82909
82910
82911
82912
82913
    sqlite3DbFree(db, pItem->zSpan);
  }
  sqlite3DbFree(db, pList->a);
  sqlite3DbFree(db, pList);
}

/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant.  The
** Walker.eCode value determines the type of "constant" we are looking
** for.
**
** These callback routines are used to implement the following:
**
**     sqlite3ExprIsConstant()                  pWalker->eCode==1
**     sqlite3ExprIsConstantNotJoin()           pWalker->eCode==2
**     sqlite3ExprRefOneTableOnly()             pWalker->eCode==3
**     sqlite3ExprIsConstantOrFunction()        pWalker->eCode==4 or 5
**
** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
** is found to not be a constant.
**
** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
** in a CREATE TABLE statement.  The Walker.eCode value is 5 when parsing
** an existing schema and 4 when processing a new statement.  A bound
** parameter raises an error for new statements, but is silently converted
** to NULL for existing schemas.  This allows sqlite_master tables that 
** contain a bound parameter because they were generated by older versions
** of SQLite to be parsed by newer versions of SQLite without raising a
** malformed schema error.
*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){

  /* If pWalker->eCode is 2 then any term of the expression that comes from
  ** the ON or USING clauses of a left join disqualifies the expression
  ** from being considered constant. */
  if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
    pWalker->eCode = 0;
    return WRC_Abort;
  }

  switch( pExpr->op ){
    /* Consider functions to be constant if all their arguments are constant
    ** and either pWalker->eCode==4 or 5 or the function has the
    ** SQLITE_FUNC_CONST flag. */
    case TK_FUNCTION:
      if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_Constant) ){
        return WRC_Continue;
      }else{
        pWalker->eCode = 0;
        return WRC_Abort;
      }

    case TK_ID:
    case TK_COLUMN:
    case TK_AGG_FUNCTION:
    case TK_AGG_COLUMN:
      testcase( pExpr->op==TK_ID );
      testcase( pExpr->op==TK_COLUMN );
      testcase( pExpr->op==TK_AGG_FUNCTION );
      testcase( pExpr->op==TK_AGG_COLUMN );
      if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
        return WRC_Continue;
      }else{
        pWalker->eCode = 0;
        return WRC_Abort;
      }
    case TK_VARIABLE:
      if( pWalker->eCode==5 ){
        /* Silently convert bound parameters that appear inside of CREATE
        ** statements into a NULL when parsing the CREATE statement text out
        ** of the sqlite_master table */
        pExpr->op = TK_NULL;
      }else if( pWalker->eCode==4 ){
        /* A bound parameter in a CREATE statement that originates from
        ** sqlite3_prepare() causes an error */
        pWalker->eCode = 0;
        return WRC_Abort;
      }
      /* Fall through */
    default:
      testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
      testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
      return WRC_Continue;
  }
}
static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  pWalker->eCode = 0;
  return WRC_Abort;
}
static int exprIsConst(Expr *p, int initFlag, int iCur){
  Walker w;
  memset(&w, 0, sizeof(w));
  w.eCode = initFlag;
  w.xExprCallback = exprNodeIsConstant;
  w.xSelectCallback = selectNodeIsConstant;
  w.u.iCur = iCur;
  sqlite3WalkExpr(&w, p);
  return w.eCode;
}

/*
** Walk an expression tree.  Return non-zero if the expression is constant
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
  return exprIsConst(p, 1, 0);
}

/*
** Walk an expression tree.  Return non-zero if the expression is constant
** that does no originate from the ON or USING clauses of a join.
** Return 0 if it involves variables or function calls or terms from
** an ON or USING clause.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
  return exprIsConst(p, 2, 0);
}

/*
** Walk an expression tree.  Return non-zero if the expression constant
** for any single row of the table with cursor iCur.  In other words, the
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
*/
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
  return exprIsConst(p, 3, iCur);
}

/*
** Walk an expression tree.  Return non-zero if the expression is constant
** or a function call with constant arguments.  Return and 0 if there
** are any variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
  assert( isInit==0 || isInit==1 );
  return exprIsConst(p, 4+isInit, 0);
}

/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
82339
82340
82341
82342
82343
82344
82345
82346
82347
82348
82349
82350
82351
82352
82353

        assert( !isRowid );
        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affSdst = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pSelect->iLimit = 0;
        testcase( pSelect->selFlags & SF_Distinct );
        pSelect->selFlags &= ~SF_Distinct;
        testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
        if( sqlite3Select(pParse, pSelect, &dest) ){
          sqlite3KeyInfoUnref(pKeyInfo);
          return 0;
        }
        pEList = pSelect->pEList;
        assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */







<







83409
83410
83411
83412
83413
83414
83415

83416
83417
83418
83419
83420
83421
83422

        assert( !isRowid );
        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affSdst = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pSelect->iLimit = 0;
        testcase( pSelect->selFlags & SF_Distinct );

        testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
        if( sqlite3Select(pParse, pSelect, &dest) ){
          sqlite3KeyInfoUnref(pKeyInfo);
          return 0;
        }
        pEList = pSelect->pEList;
        assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
83486
83487
83488
83489
83490
83491
83492
83493



83494
83495
83496
83497
83498
83499
83500
        (pExpr->iTable ? "new" : "old"),
        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
        target
      ));

#ifndef SQLITE_OMIT_FLOATING_POINT
      /* If the column has REAL affinity, it may currently be stored as an
      ** integer. Use OP_RealAffinity to make sure it is really real.  */



      if( pExpr->iColumn>=0 
       && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
      ){
        sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
      }
#endif
      break;







|
>
>
>







84555
84556
84557
84558
84559
84560
84561
84562
84563
84564
84565
84566
84567
84568
84569
84570
84571
84572
        (pExpr->iTable ? "new" : "old"),
        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
        target
      ));

#ifndef SQLITE_OMIT_FLOATING_POINT
      /* If the column has REAL affinity, it may currently be stored as an
      ** integer. Use OP_RealAffinity to make sure it is really real.
      **
      ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
      ** floating point when extracting it from the record.  */
      if( pExpr->iColumn>=0 
       && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
      ){
        sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
      }
#endif
      break;
83739
83740
83741
83742
83743
83744
83745
83746
83747
83748
83749
83750
83751
83752
83753

83754

83755
83756
83757
83758
83759
83760
83761
83762
83763
83764
83765
83766
83767
83768
83769
83770
83771
83772
83773
83774
83775
83776
83777
83778
83779
83780
83781
83782
83783
83784
83785
83786
83787
83788
83789
83790
83791
83792
83793
83794
83795
83796
83797
83798
83799
83800
83801
83802
83803
83804
83805
83806
83807
83808
83809
83810
83811
83812

83813




83814
83815
83816
83817
83818
83819
83820
83821
83822
83823
83824
83825
83826
83827
83828
83829
83830
83831
83832
83833
83834
83835
83836
  assert( pExpr->op!=TK_REGISTER );
  sqlite3ExprCode(pParse, pExpr, target);
  iMem = ++pParse->nMem;
  sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
  exprToRegister(pExpr, iMem);
}

#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Generate a human-readable explanation of an expression tree.
*/
SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
  int op;                   /* The opcode being coded */
  const char *zBinOp = 0;   /* Binary operator */
  const char *zUniOp = 0;   /* Unary operator */

  if( pExpr==0 ){

    op = TK_NULL;
  }else{
    op = pExpr->op;
  }
  switch( op ){
    case TK_AGG_COLUMN: {
      sqlite3ExplainPrintf(pOut, "AGG{%d:%d}",
            pExpr->iTable, pExpr->iColumn);
      break;
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
      }else{
        sqlite3ExplainPrintf(pOut, "{%d:%d}",
                             pExpr->iTable, pExpr->iColumn);
      }
      break;
    }
    case TK_INTEGER: {
      if( pExpr->flags & EP_IntValue ){
        sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue);
      }else{
        sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken);
      }
      break;
    }
#ifndef SQLITE_OMIT_FLOATING_POINT
    case TK_FLOAT: {
      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
      break;
    }
#endif
    case TK_STRING: {
      sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
      break;
    }
    case TK_NULL: {
      sqlite3ExplainPrintf(pOut,"NULL");
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {
      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
      break;
    }
#endif
    case TK_VARIABLE: {
      sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)",
                           pExpr->u.zToken, pExpr->iColumn);
      break;
    }
    case TK_REGISTER: {
      sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
      break;
    }
    case TK_AS: {

      sqlite3ExplainExpr(pOut, pExpr->pLeft);




      break;
    }
#ifndef SQLITE_OMIT_CAST
    case TK_CAST: {
      /* Expressions of the form:   CAST(pLeft AS token) */
      const char *zAff = "unk";
      switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){
        case SQLITE_AFF_TEXT:    zAff = "TEXT";     break;
        case SQLITE_AFF_NONE:    zAff = "NONE";     break;
        case SQLITE_AFF_NUMERIC: zAff = "NUMERIC";  break;
        case SQLITE_AFF_INTEGER: zAff = "INTEGER";  break;
        case SQLITE_AFF_REAL:    zAff = "REAL";     break;
      }
      sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff);
      sqlite3ExplainExpr(pOut, pExpr->pLeft);
      sqlite3ExplainPrintf(pOut, ")");
      break;
    }
#endif /* SQLITE_OMIT_CAST */
    case TK_LT:      zBinOp = "LT";     break;
    case TK_LE:      zBinOp = "LE";     break;
    case TK_GT:      zBinOp = "GT";     break;
    case TK_GE:      zBinOp = "GE";     break;







|



|
<


>

>
|
|
<

|

|






|

|






|

|





|




|



|




|




|
|



|



>
|
>
>
>
>





<
|
<
<
<
<
<
<
<
|
<







84811
84812
84813
84814
84815
84816
84817
84818
84819
84820
84821
84822

84823
84824
84825
84826
84827
84828
84829

84830
84831
84832
84833
84834
84835
84836
84837
84838
84839
84840
84841
84842
84843
84844
84845
84846
84847
84848
84849
84850
84851
84852
84853
84854
84855
84856
84857
84858
84859
84860
84861
84862
84863
84864
84865
84866
84867
84868
84869
84870
84871
84872
84873
84874
84875
84876
84877
84878
84879
84880
84881
84882
84883
84884
84885
84886
84887
84888
84889
84890
84891
84892
84893
84894
84895

84896







84897

84898
84899
84900
84901
84902
84903
84904
  assert( pExpr->op!=TK_REGISTER );
  sqlite3ExprCode(pParse, pExpr, target);
  iMem = ++pParse->nMem;
  sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
  exprToRegister(pExpr, iMem);
}

#ifdef SQLITE_DEBUG
/*
** Generate a human-readable explanation of an expression tree.
*/
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){

  const char *zBinOp = 0;   /* Binary operator */
  const char *zUniOp = 0;   /* Unary operator */
  pView = sqlite3TreeViewPush(pView, moreToFollow);
  if( pExpr==0 ){
    sqlite3TreeViewLine(pView, "nil");
    sqlite3TreeViewPop(pView);
    return;

  }
  switch( pExpr->op ){
    case TK_AGG_COLUMN: {
      sqlite3TreeViewLine(pView, "AGG{%d:%d}",
            pExpr->iTable, pExpr->iColumn);
      break;
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
      }else{
        sqlite3TreeViewLine(pView, "{%d:%d}",
                             pExpr->iTable, pExpr->iColumn);
      }
      break;
    }
    case TK_INTEGER: {
      if( pExpr->flags & EP_IntValue ){
        sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
      }else{
        sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
      }
      break;
    }
#ifndef SQLITE_OMIT_FLOATING_POINT
    case TK_FLOAT: {
      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
      break;
    }
#endif
    case TK_STRING: {
      sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
      break;
    }
    case TK_NULL: {
      sqlite3TreeViewLine(pView,"NULL");
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {
      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
      break;
    }
#endif
    case TK_VARIABLE: {
      sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
                          pExpr->u.zToken, pExpr->iColumn);
      break;
    }
    case TK_REGISTER: {
      sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
      break;
    }
    case TK_AS: {
      sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      break;
    }
    case TK_ID: {
      sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
      break;
    }
#ifndef SQLITE_OMIT_CAST
    case TK_CAST: {
      /* Expressions of the form:   CAST(pLeft AS token) */

      sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);







      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);

      break;
    }
#endif /* SQLITE_OMIT_CAST */
    case TK_LT:      zBinOp = "LT";     break;
    case TK_LE:      zBinOp = "LE";     break;
    case TK_GT:      zBinOp = "GT";     break;
    case TK_GE:      zBinOp = "GE";     break;
83846
83847
83848
83849
83850
83851
83852

83853
83854
83855
83856
83857
83858
83859
83860
83861

83862
83863
83864
83865
83866
83867
83868
83869
83870
83871
83872
83873
83874
83875
83876
83877
83878
83879
83880
83881
83882
83883
83884
83885
83886
83887
83888
83889
83890
83891
83892
83893
83894
83895
83896
83897
83898
83899
83900
83901
83902
83903
83904
83905
83906
83907
83908
83909
83910
83911
83912
83913
83914
83915
83916
83917
83918
83919
83920
83921
83922
83923
83924
83925
83926
83927
83928
83929
83930
83931
83932
83933
83934
83935
83936
83937
83938
83939
83940
83941
83942
83943
83944
83945
83946
83947
83948
83949
83950
83951
83952
83953
83954
83955
83956
83957
83958
83959
83960
83961
83962
83963
83964
83965
83966
83967
83968
83969



83970

83971
83972
83973
83974
83975
83976
83977
83978
83979
83980
83981

83982
83983
83984
83985
83986
83987
83988
83989





83990


83991
83992
83993
83994
83995
83996
83997
83998
83999
84000
84001
84002

84003
84004
84005
84006
84007
84008
84009
84010
84011
84012
84013
84014
84015
84016
84017
84018
84019
84020
84021
    case TK_REM:     zBinOp = "REM";    break;
    case TK_BITAND:  zBinOp = "BITAND"; break;
    case TK_BITOR:   zBinOp = "BITOR";  break;
    case TK_SLASH:   zBinOp = "DIV";    break;
    case TK_LSHIFT:  zBinOp = "LSHIFT"; break;
    case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
    case TK_CONCAT:  zBinOp = "CONCAT"; break;


    case TK_UMINUS:  zUniOp = "UMINUS"; break;
    case TK_UPLUS:   zUniOp = "UPLUS";  break;
    case TK_BITNOT:  zUniOp = "BITNOT"; break;
    case TK_NOT:     zUniOp = "NOT";    break;
    case TK_ISNULL:  zUniOp = "ISNULL"; break;
    case TK_NOTNULL: zUniOp = "NOTNULL"; break;

    case TK_COLLATE: {

      sqlite3ExplainExpr(pOut, pExpr->pLeft);
      sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
      break;
    }

    case TK_AGG_FUNCTION:
    case TK_FUNCTION: {
      ExprList *pFarg;       /* List of function arguments */
      if( ExprHasProperty(pExpr, EP_TokenOnly) ){
        pFarg = 0;
      }else{
        pFarg = pExpr->x.pList;
      }
      if( op==TK_AGG_FUNCTION ){
        sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
                             pExpr->op2, pExpr->u.zToken);
      }else{
        sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
      }
      if( pFarg ){
        sqlite3ExplainExprList(pOut, pFarg);
      }
      sqlite3ExplainPrintf(pOut, ")");
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS: {
      sqlite3ExplainPrintf(pOut, "EXISTS(");
      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
      sqlite3ExplainPrintf(pOut,")");
      break;
    }
    case TK_SELECT: {
      sqlite3ExplainPrintf(pOut, "(");
      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
      sqlite3ExplainPrintf(pOut, ")");
      break;
    }
    case TK_IN: {
      sqlite3ExplainPrintf(pOut, "IN(");
      sqlite3ExplainExpr(pOut, pExpr->pLeft);
      sqlite3ExplainPrintf(pOut, ",");
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
      }else{
        sqlite3ExplainExprList(pOut, pExpr->x.pList);
      }
      sqlite3ExplainPrintf(pOut, ")");
      break;
    }
#endif /* SQLITE_OMIT_SUBQUERY */

    /*
    **    x BETWEEN y AND z
    **
    ** This is equivalent to
    **
    **    x>=y AND x<=z
    **
    ** X is stored in pExpr->pLeft.
    ** Y is stored in pExpr->pList->a[0].pExpr.
    ** Z is stored in pExpr->pList->a[1].pExpr.
    */
    case TK_BETWEEN: {
      Expr *pX = pExpr->pLeft;
      Expr *pY = pExpr->x.pList->a[0].pExpr;
      Expr *pZ = pExpr->x.pList->a[1].pExpr;
      sqlite3ExplainPrintf(pOut, "BETWEEN(");
      sqlite3ExplainExpr(pOut, pX);
      sqlite3ExplainPrintf(pOut, ",");
      sqlite3ExplainExpr(pOut, pY);
      sqlite3ExplainPrintf(pOut, ",");
      sqlite3ExplainExpr(pOut, pZ);
      sqlite3ExplainPrintf(pOut, ")");
      break;
    }
    case TK_TRIGGER: {
      /* If the opcode is TK_TRIGGER, then the expression is a reference
      ** to a column in the new.* or old.* pseudo-tables available to
      ** trigger programs. In this case Expr.iTable is set to 1 for the
      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
      ** is set to the column of the pseudo-table to read, or to -1 to
      ** read the rowid field.
      */
      sqlite3ExplainPrintf(pOut, "%s(%d)", 
          pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
      break;
    }
    case TK_CASE: {
      sqlite3ExplainPrintf(pOut, "CASE(");
      sqlite3ExplainExpr(pOut, pExpr->pLeft);
      sqlite3ExplainPrintf(pOut, ",");
      sqlite3ExplainExprList(pOut, pExpr->x.pList);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      const char *zType = "unk";
      switch( pExpr->affinity ){
        case OE_Rollback:   zType = "rollback";  break;
        case OE_Abort:      zType = "abort";     break;
        case OE_Fail:       zType = "fail";      break;
        case OE_Ignore:     zType = "ignore";    break;
      }
      sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
      break;
    }
#endif



  }

  if( zBinOp ){
    sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
    sqlite3ExplainExpr(pOut, pExpr->pLeft);
    sqlite3ExplainPrintf(pOut,",");
    sqlite3ExplainExpr(pOut, pExpr->pRight);
    sqlite3ExplainPrintf(pOut,")");
  }else if( zUniOp ){
    sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
    sqlite3ExplainExpr(pOut, pExpr->pLeft);
    sqlite3ExplainPrintf(pOut,")");
  }

}
#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */

#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Generate a human-readable explanation of an expression list.
*/
SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){





  int i;


  if( pList==0 || pList->nExpr==0 ){
    sqlite3ExplainPrintf(pOut, "(empty-list)");
    return;
  }else if( pList->nExpr==1 ){
    sqlite3ExplainExpr(pOut, pList->a[0].pExpr);
  }else{
    sqlite3ExplainPush(pOut);
    for(i=0; i<pList->nExpr; i++){
      sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
      sqlite3ExplainPush(pOut);
      sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
      sqlite3ExplainPop(pOut);

      if( pList->a[i].zName ){
        sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
      }
      if( pList->a[i].bSpanIsTab ){
        sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
      }
      if( i<pList->nExpr-1 ){
        sqlite3ExplainNL(pOut);
      }
    }
    sqlite3ExplainPop(pOut);
  }
}
#endif /* SQLITE_DEBUG */

/*
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**







>









>
|
<











|
|


|


|

<




|
|
<



|
|
<



|
|
<

|

|

<



















|
|
<
|
<
|
<










|




|
|
<
|











|



>
>
>
|
>

|
|
<
|
<

|
|
<

>

|

|



|
>
>
>
>
>

>
>
|
|
<
<
<

|

<
<
|
<
>
|





|
<
|
|
|
<







84914
84915
84916
84917
84918
84919
84920
84921
84922
84923
84924
84925
84926
84927
84928
84929
84930
84931
84932

84933
84934
84935
84936
84937
84938
84939
84940
84941
84942
84943
84944
84945
84946
84947
84948
84949
84950
84951
84952

84953
84954
84955
84956
84957
84958

84959
84960
84961
84962
84963

84964
84965
84966
84967
84968

84969
84970
84971
84972
84973

84974
84975
84976
84977
84978
84979
84980
84981
84982
84983
84984
84985
84986
84987
84988
84989
84990
84991
84992
84993
84994

84995

84996

84997
84998
84999
85000
85001
85002
85003
85004
85005
85006
85007
85008
85009
85010
85011
85012
85013

85014
85015
85016
85017
85018
85019
85020
85021
85022
85023
85024
85025
85026
85027
85028
85029
85030
85031
85032
85033
85034
85035
85036
85037

85038

85039
85040
85041

85042
85043
85044
85045
85046
85047
85048
85049
85050
85051
85052
85053
85054
85055
85056
85057
85058
85059
85060
85061



85062
85063
85064


85065

85066
85067
85068
85069
85070
85071
85072
85073

85074
85075
85076

85077
85078
85079
85080
85081
85082
85083
    case TK_REM:     zBinOp = "REM";    break;
    case TK_BITAND:  zBinOp = "BITAND"; break;
    case TK_BITOR:   zBinOp = "BITOR";  break;
    case TK_SLASH:   zBinOp = "DIV";    break;
    case TK_LSHIFT:  zBinOp = "LSHIFT"; break;
    case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
    case TK_CONCAT:  zBinOp = "CONCAT"; break;
    case TK_DOT:     zBinOp = "DOT";    break;

    case TK_UMINUS:  zUniOp = "UMINUS"; break;
    case TK_UPLUS:   zUniOp = "UPLUS";  break;
    case TK_BITNOT:  zUniOp = "BITNOT"; break;
    case TK_NOT:     zUniOp = "NOT";    break;
    case TK_ISNULL:  zUniOp = "ISNULL"; break;
    case TK_NOTNULL: zUniOp = "NOTNULL"; break;

    case TK_COLLATE: {
      sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);

      break;
    }

    case TK_AGG_FUNCTION:
    case TK_FUNCTION: {
      ExprList *pFarg;       /* List of function arguments */
      if( ExprHasProperty(pExpr, EP_TokenOnly) ){
        pFarg = 0;
      }else{
        pFarg = pExpr->x.pList;
      }
      if( pExpr->op==TK_AGG_FUNCTION ){
        sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
                             pExpr->op2, pExpr->u.zToken);
      }else{
        sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
      }
      if( pFarg ){
        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
      }

      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS: {
      sqlite3TreeViewLine(pView, "EXISTS-expr");
      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);

      break;
    }
    case TK_SELECT: {
      sqlite3TreeViewLine(pView, "SELECT-expr");
      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);

      break;
    }
    case TK_IN: {
      sqlite3TreeViewLine(pView, "IN");
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
      }else{
        sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
      }

      break;
    }
#endif /* SQLITE_OMIT_SUBQUERY */

    /*
    **    x BETWEEN y AND z
    **
    ** This is equivalent to
    **
    **    x>=y AND x<=z
    **
    ** X is stored in pExpr->pLeft.
    ** Y is stored in pExpr->pList->a[0].pExpr.
    ** Z is stored in pExpr->pList->a[1].pExpr.
    */
    case TK_BETWEEN: {
      Expr *pX = pExpr->pLeft;
      Expr *pY = pExpr->x.pList->a[0].pExpr;
      Expr *pZ = pExpr->x.pList->a[1].pExpr;
      sqlite3TreeViewLine(pView, "BETWEEN");
      sqlite3TreeViewExpr(pView, pX, 1);

      sqlite3TreeViewExpr(pView, pY, 1);

      sqlite3TreeViewExpr(pView, pZ, 0);

      break;
    }
    case TK_TRIGGER: {
      /* If the opcode is TK_TRIGGER, then the expression is a reference
      ** to a column in the new.* or old.* pseudo-tables available to
      ** trigger programs. In this case Expr.iTable is set to 1 for the
      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
      ** is set to the column of the pseudo-table to read, or to -1 to
      ** read the rowid field.
      */
      sqlite3TreeViewLine(pView, "%s(%d)", 
          pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
      break;
    }
    case TK_CASE: {
      sqlite3TreeViewLine(pView, "CASE");
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);

      sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      const char *zType = "unk";
      switch( pExpr->affinity ){
        case OE_Rollback:   zType = "rollback";  break;
        case OE_Abort:      zType = "abort";     break;
        case OE_Fail:       zType = "fail";      break;
        case OE_Ignore:     zType = "ignore";    break;
      }
      sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
      break;
    }
#endif
    default: {
      sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
      break;
    }
  }
  if( zBinOp ){
    sqlite3TreeViewLine(pView, "%s", zBinOp);
    sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);

    sqlite3TreeViewExpr(pView, pExpr->pRight, 0);

  }else if( zUniOp ){
    sqlite3TreeViewLine(pView, "%s", zUniOp);
    sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);

  }
  sqlite3TreeViewPop(pView);
}
#endif /* SQLITE_DEBUG */

#ifdef SQLITE_DEBUG
/*
** Generate a human-readable explanation of an expression list.
*/
SQLITE_PRIVATE void sqlite3TreeViewExprList(
  TreeView *pView,
  const ExprList *pList,
  u8 moreToFollow,
  const char *zLabel
){
  int i;
  pView = sqlite3TreeViewPush(pView, moreToFollow);
  if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
  if( pList==0 ){
    sqlite3TreeViewLine(pView, "%s (empty)", zLabel);



  }else{
    sqlite3TreeViewLine(pView, "%s", zLabel);
    for(i=0; i<pList->nExpr; i++){


      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);

#if 0
     if( pList->a[i].zName ){
        sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
      }
      if( pList->a[i].bSpanIsTab ){
        sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
      }
#endif

    }
  }
  sqlite3TreeViewPop(pView);

}
#endif /* SQLITE_DEBUG */

/*
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**
87128
87129
87130
87131
87132
87133
87134
87135
87136
87137
87138
87139
87140
87141
87142
87143
87144
87145
87146
87147
87148
87149
87150
87151
87152
87153

87154
87155
87156
87157
87158
87159
87160


87161
87162
87163
87164
87165


87166
87167
87168
87169
87170
87171
87172
87173

87174
87175
87176
87177
87178
87179
87180
  int c;
  int i;
  tRowcnt v;

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( z==0 ) z = "";
#else
  if( NEVER(z==0) ) z = "";
#endif
  for(i=0; *z && i<nOut; i++){
    v = 0;
    while( (c=z[0])>='0' && c<='9' ){
      v = v*10 + c - '0';
      z++;
    }
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    if( aOut ){
      aOut[i] = v;
    }else
#else
    assert( aOut==0 );
    UNUSED_PARAMETER(aOut);
#endif
    {
      aLog[i] = sqlite3LogEst(v);
    }

    if( *z==' ' ) z++;
  }
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
  assert( pIndex!=0 );
#else
  if( pIndex )
#endif


  while( z[0] ){
    if( sqlite3_strglob("unordered*", z)==0 ){
      pIndex->bUnordered = 1;
    }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
      pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));


    }
#ifdef SQLITE_ENABLE_COSTMULT
    else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
      pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
    }
#endif
    while( z[0]!=0 && z[0]!=' ' ) z++;
    while( z[0]==' ' ) z++;

  }
}

/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.  
**







|








|
|
<



|
<
|
<
>



|

|

>
>
|
|
|
|
|
>
>
|

|
|
|

|
|
>







88190
88191
88192
88193
88194
88195
88196
88197
88198
88199
88200
88201
88202
88203
88204
88205
88206
88207

88208
88209
88210
88211

88212

88213
88214
88215
88216
88217
88218
88219
88220
88221
88222
88223
88224
88225
88226
88227
88228
88229
88230
88231
88232
88233
88234
88235
88236
88237
88238
88239
88240
88241
88242
88243
88244
88245
  int c;
  int i;
  tRowcnt v;

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( z==0 ) z = "";
#else
  assert( z!=0 );
#endif
  for(i=0; *z && i<nOut; i++){
    v = 0;
    while( (c=z[0])>='0' && c<='9' ){
      v = v*10 + c - '0';
      z++;
    }
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    if( aOut ) aOut[i] = v;
    if( aLog ) aLog[i] = sqlite3LogEst(v);

#else
    assert( aOut==0 );
    UNUSED_PARAMETER(aOut);
    assert( aLog!=0 );

    aLog[i] = sqlite3LogEst(v);

#endif
    if( *z==' ' ) z++;
  }
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
  assert( pIndex!=0 ); {
#else
  if( pIndex ){
#endif
    pIndex->bUnordered = 0;
    pIndex->noSkipScan = 0;
    while( z[0] ){
      if( sqlite3_strglob("unordered*", z)==0 ){
        pIndex->bUnordered = 1;
      }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
        pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
      }else if( sqlite3_strglob("noskipscan*", z)==0 ){
        pIndex->noSkipScan = 1;
      }
#ifdef SQLITE_ENABLE_COSTMULT
      else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
        pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
      }
#endif
      while( z[0]!=0 && z[0]!=' ' ) z++;
      while( z[0]==' ' ) z++;
    }
  }
}

/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.  
**
87207
87208
87209
87210
87211
87212
87213









87214
87215
87216
87217
87218
87219
87220
87221
87222
    pIndex = sqlite3PrimaryKeyIndex(pTable);
  }else{
    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  }
  z = argv[2];

  if( pIndex ){









    pIndex->bUnordered = 0;
    decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
    if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
  }else{
    Index fakeIdx;
    fakeIdx.szIdxRow = pTable->szTabRow;
#ifdef SQLITE_ENABLE_COSTMULT
    fakeIdx.pTable = pTable;
#endif







>
>
>
>
>
>
>
>
>

|







88272
88273
88274
88275
88276
88277
88278
88279
88280
88281
88282
88283
88284
88285
88286
88287
88288
88289
88290
88291
88292
88293
88294
88295
88296
    pIndex = sqlite3PrimaryKeyIndex(pTable);
  }else{
    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  }
  z = argv[2];

  if( pIndex ){
    int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
        sizeof(tRowcnt) * nCol
    );
    if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
#else
    tRowcnt * const aiRowEst = 0;
#endif
    pIndex->bUnordered = 0;
    decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
    if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
  }else{
    Index fakeIdx;
    fakeIdx.szIdxRow = pTable->szTabRow;
#ifdef SQLITE_ENABLE_COSTMULT
    fakeIdx.pTable = pTable;
#endif
87267
87268
87269
87270
87271
87272
87273

87274
87275
87276
87277






87278




87279


87280
87281
87282
87283
87284

87285
87286

87287
87288
87289
87290
87291

87292
87293
87294
87295
87296
87297
87298
87299
      ** sample columns except the last. The last is always set to 1, as
      ** once the trailing PK fields are considered all index keys are
      ** unique.  */
      nCol = pIdx->nSampleCol-1;
      pIdx->aAvgEq[nCol] = 1;
    }
    for(iCol=0; iCol<nCol; iCol++){

      int i;                    /* Used to iterate through samples */
      tRowcnt sumEq = 0;        /* Sum of the nEq values */
      tRowcnt nSum = 0;         /* Number of terms contributing to sumEq */
      tRowcnt avgEq = 0;






      tRowcnt nDLt = pFinal->anDLt[iCol];







      /* Set nSum to the number of distinct (iCol+1) field prefixes that
      ** occur in the stat4 table for this index before pFinal. Set
      ** sumEq to the sum of the nEq values for column iCol for the same
      ** set (adding the value only once where there exist duplicate 
      ** prefixes).  */

      for(i=0; i<(pIdx->nSample-1); i++){
        if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){

          sumEq += aSample[i].anEq[iCol];
          nSum++;
        }
      }
      if( nDLt>nSum ){

        avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
      }
      if( avgEq==0 ) avgEq = 1;
      pIdx->aAvgEq[iCol] = avgEq;
    }
  }
}








>


<

>
>
>
>
>
>
|
>
>
>
>
|
>
>

|
|
|
<
>
|
|
>

|


|
>
|







88341
88342
88343
88344
88345
88346
88347
88348
88349
88350

88351
88352
88353
88354
88355
88356
88357
88358
88359
88360
88361
88362
88363
88364
88365
88366
88367
88368
88369

88370
88371
88372
88373
88374
88375
88376
88377
88378
88379
88380
88381
88382
88383
88384
88385
88386
88387
      ** sample columns except the last. The last is always set to 1, as
      ** once the trailing PK fields are considered all index keys are
      ** unique.  */
      nCol = pIdx->nSampleCol-1;
      pIdx->aAvgEq[nCol] = 1;
    }
    for(iCol=0; iCol<nCol; iCol++){
      int nSample = pIdx->nSample;
      int i;                    /* Used to iterate through samples */
      tRowcnt sumEq = 0;        /* Sum of the nEq values */

      tRowcnt avgEq = 0;
      tRowcnt nRow;             /* Number of rows in index */
      i64 nSum100 = 0;          /* Number of terms contributing to sumEq */
      i64 nDist100;             /* Number of distinct values in index */

      if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
        nRow = pFinal->anLt[iCol];
        nDist100 = (i64)100 * pFinal->anDLt[iCol];
        nSample--;
      }else{
        nRow = pIdx->aiRowEst[0];
        nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
      }
      pIdx->nRowEst0 = nRow;

      /* Set nSum to the number of distinct (iCol+1) field prefixes that
      ** occur in the stat4 table for this index. Set sumEq to the sum of 
      ** the nEq values for column iCol for the same set (adding the value 
      ** only once where there exist duplicate prefixes).  */

      for(i=0; i<nSample; i++){
        if( i==(pIdx->nSample-1)
         || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] 
        ){
          sumEq += aSample[i].anEq[iCol];
          nSum100 += 100;
        }
      }

      if( nDist100>nSum100 ){
        avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
      }
      if( avgEq==0 ) avgEq = 1;
      pIdx->aAvgEq[iCol] = avgEq;
    }
  }
}

87531
87532
87533
87534
87535
87536
87537
87538
87539
87540
87541
87542





87543
87544
87545
87546
87547
87548
87549
    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
    sqlite3DbFree(db, zSql);
  }


  /* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( rc==SQLITE_OK ){
    int lookasideEnabled = db->lookaside.bEnabled;
    db->lookaside.bEnabled = 0;
    rc = loadStat4(db, sInfo.zDatabase);
    db->lookaside.bEnabled = lookasideEnabled;





  }
#endif

  if( rc==SQLITE_NOMEM ){
    db->mallocFailed = 1;
  }
  return rc;







|




>
>
>
>
>







88619
88620
88621
88622
88623
88624
88625
88626
88627
88628
88629
88630
88631
88632
88633
88634
88635
88636
88637
88638
88639
88640
88641
88642
    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
    sqlite3DbFree(db, zSql);
  }


  /* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
    int lookasideEnabled = db->lookaside.bEnabled;
    db->lookaside.bEnabled = 0;
    rc = loadStat4(db, sInfo.zDatabase);
    db->lookaside.bEnabled = lookasideEnabled;
  }
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    sqlite3_free(pIdx->aiRowEst);
    pIdx->aiRowEst = 0;
  }
#endif

  if( rc==SQLITE_NOMEM ){
    db->mallocFailed = 1;
  }
  return rc;
88208
88209
88210
88211
88212
88213
88214



88215
88216
88217
88218
88219
88220
88221
** setting of the auth function is NULL.
*/
SQLITE_API int sqlite3_set_authorizer(
  sqlite3 *db,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pArg
){



  sqlite3_mutex_enter(db->mutex);
  db->xAuth = (sqlite3_xauth)xAuth;
  db->pAuthArg = pArg;
  sqlite3ExpirePreparedStatements(db);
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}







>
>
>







89301
89302
89303
89304
89305
89306
89307
89308
89309
89310
89311
89312
89313
89314
89315
89316
89317
** setting of the auth function is NULL.
*/
SQLITE_API int sqlite3_set_authorizer(
  sqlite3 *db,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  db->xAuth = (sqlite3_xauth)xAuth;
  db->pAuthArg = pArg;
  sqlite3ExpirePreparedStatements(db);
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}
88702
88703
88704
88705
88706
88707
88708
88709




88710
88711
88712
88713
88714
88715
88716
** auxiliary databases added using the ATTACH command.
**
** See also sqlite3LocateTable().
*/
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
  Table *p = 0;
  int i;
  assert( zName!=0 );




  /* All mutexes are required for schema access.  Make sure we hold them. */
  assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
#if SQLITE_USER_AUTHENTICATION
  /* Only the admin user is allowed to know that the sqlite_user table
  ** exists */
  if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
    return 0;







|
>
>
>
>







89798
89799
89800
89801
89802
89803
89804
89805
89806
89807
89808
89809
89810
89811
89812
89813
89814
89815
89816
** auxiliary databases added using the ATTACH command.
**
** See also sqlite3LocateTable().
*/
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
  Table *p = 0;
  int i;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return 0;
#endif

  /* All mutexes are required for schema access.  Make sure we hold them. */
  assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
#if SQLITE_USER_AUTHENTICATION
  /* Only the admin user is allowed to know that the sqlite_user table
  ** exists */
  if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
    return 0;
88830
88831
88832
88833
88834
88835
88836



88837
88838
88839
88840
88841
88842
88843
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(db, p);
#endif
  if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
  sqlite3ExprDelete(db, p->pPartIdxWhere);
  sqlite3DbFree(db, p->zColAff);
  if( p->isResized ) sqlite3DbFree(db, p->azColl);



  sqlite3DbFree(db, p);
}

/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
** the index hash table and free all memory structures associated







>
>
>







89930
89931
89932
89933
89934
89935
89936
89937
89938
89939
89940
89941
89942
89943
89944
89945
89946
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(db, p);
#endif
  if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
  sqlite3ExprDelete(db, p->pPartIdxWhere);
  sqlite3DbFree(db, p->zColAff);
  if( p->isResized ) sqlite3DbFree(db, p->azColl);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  sqlite3_free(p->aiRowEst);
#endif
  sqlite3DbFree(db, p);
}

/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
** the index hash table and free all memory structures associated
89631
89632
89633
89634
89635
89636
89637
89638
89639
89640
89641
89642
89643
89644
89645
SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
  Table *p;
  Column *pCol;
  sqlite3 *db = pParse->db;
  p = pParse->pNewTable;
  if( p!=0 ){
    pCol = &(p->aCol[p->nCol-1]);
    if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
      sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
          pCol->zName);
    }else{
      /* A copy of pExpr is used instead of the original, as pExpr contains
      ** tokens that point to volatile memory. The 'span' of the expression
      ** is required by pragma table_info.
      */







|







90734
90735
90736
90737
90738
90739
90740
90741
90742
90743
90744
90745
90746
90747
90748
SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
  Table *p;
  Column *pCol;
  sqlite3 *db = pParse->db;
  p = pParse->pNewTable;
  if( p!=0 ){
    pCol = &(p->aCol[p->nCol-1]);
    if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
      sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
          pCol->zName);
    }else{
      /* A copy of pExpr is used instead of the original, as pExpr contains
      ** tokens that point to volatile memory. The 'span' of the expression
      ** is required by pragma table_info.
      */
91139
91140
91141
91142
91143
91144
91145
91146
91147
91148
91149
91150
91151
91152
91153
    addr2 = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
                         pIndex->nKeyCol); VdbeCoverage(v);
    sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
  }else{
    addr2 = sqlite3VdbeCurrentAddr(v);
  }
  sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
  sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
  sqlite3VdbeJumpHere(v, addr1);

  sqlite3VdbeAddOp1(v, OP_Close, iTab);







|







92242
92243
92244
92245
92246
92247
92248
92249
92250
92251
92252
92253
92254
92255
92256
    addr2 = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
                         pIndex->nKeyCol); VdbeCoverage(v);
    sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
  }else{
    addr2 = sqlite3VdbeCurrentAddr(v);
  }
  sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
  sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
  sqlite3VdbeJumpHere(v, addr1);

  sqlite3VdbeAddOp1(v, OP_Close, iTab);
93647
93648
93649
93650
93651
93652
93653
93654
93655
93656
93657
93658
93659
93660
93661
    ** where-clause loop above.
    */
    if( okOnePass ){
      /* Just one row.  Hence the top-of-loop is a no-op */
      assert( nKey==nPk );  /* OP_Found will use an unpacked key */
      assert( !IsVirtual(pTab) );
      if( aToOpen[iDataCur-iTabCur] ){
        assert( pPk!=0 );
        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
        VdbeCoverage(v);
      }
    }else if( pPk ){
      addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
      sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
      assert( nKey==0 );  /* OP_Found will use a composite key */







|







94750
94751
94752
94753
94754
94755
94756
94757
94758
94759
94760
94761
94762
94763
94764
    ** where-clause loop above.
    */
    if( okOnePass ){
      /* Just one row.  Hence the top-of-loop is a no-op */
      assert( nKey==nPk );  /* OP_Found will use an unpacked key */
      assert( !IsVirtual(pTab) );
      if( aToOpen[iDataCur-iTabCur] ){
        assert( pPk!=0 || pTab->pSelect!=0 );
        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
        VdbeCoverage(v);
      }
    }else if( pPk ){
      addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
      sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
      assert( nKey==0 );  /* OP_Found will use a composite key */
94028
94029
94030
94031
94032
94033
94034



94035
94036
94037
94038
94039
94040
94041
94042
/* #include <stdlib.h> */
/* #include <assert.h> */

/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){



  return context->pColl;
}

/*
** Indicate that the accumulator load should be skipped on this
** iteration of the aggregate loop.
*/
static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){







>
>
>
|







95131
95132
95133
95134
95135
95136
95137
95138
95139
95140
95141
95142
95143
95144
95145
95146
95147
95148
/* #include <stdlib.h> */
/* #include <assert.h> */

/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
  VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
  assert( pOp->opcode==OP_CollSeq );
  assert( pOp->p4type==P4_COLLSEQ );
  return pOp->p4.pColl;
}

/*
** Indicate that the accumulator load should be skipped on this
** iteration of the aggregate loop.
*/
static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
94160
94161
94162
94163
94164
94165
94166
94167
94168
94169
94170
94171
94172
94173
94174
94175
      /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */
      sqlite3_result_null(context);
      break;
    }
    default: {
      /* Because sqlite3_value_double() returns 0.0 if the argument is not
      ** something that can be converted into a number, we have:
      ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
      ** cannot be converted to a numeric value. 
      */
      double rVal = sqlite3_value_double(argv[0]);
      if( rVal<0 ) rVal = -rVal;
      sqlite3_result_double(context, rVal);
      break;
    }
  }







|
|







95266
95267
95268
95269
95270
95271
95272
95273
95274
95275
95276
95277
95278
95279
95280
95281
      /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */
      sqlite3_result_null(context);
      break;
    }
    default: {
      /* Because sqlite3_value_double() returns 0.0 if the argument is not
      ** something that can be converted into a number, we have:
      ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob
      ** that cannot be converted to a numeric value.
      */
      double rVal = sqlite3_value_double(argv[0]);
      if( rVal<0 ) rVal = -rVal;
      sqlite3_result_double(context, rVal);
      break;
    }
  }
94573
94574
94575
94576
94577
94578
94579
94580
94581

94582
94583

94584
94585
94586
94587
94588
94589
94590
94591
94592
94593
94594
94595
94596
94597
94598
94599
94600
94601
94602
94603
94604
94605
94606
94607
94608
94609
94610
94611
94612
94613
94614
94615
94616
94617
94618
94619
94620







94621
94622
94623
94624
94625
94626
94627
94628
94629
94630
94631
94632
94633
94634

94635






94636
94637
94638



94639
94640
94641
94642
94643
94644
94645
94646
94647

94648
94649
94650
94651
94652
94653
94654

94655
94656
94657
94658
94659

94660









94661
94662
94663
94664

94665
94666
94667
94668
94669
94670
94671



94672


94673
94674
94675

94676

94677

94678
94679

94680
94681
94682
94683
94684
94685
94686
94687
94688
94689
94690
94691
94692
94693
94694
94695
94696
94697
94698
94699
94700
94701
94702
94703
94704
94705
94706
94707
94708
94709
94710
94711
94712
94713
94714
94715


94716
94717
94718
94719
94720
94721
94722
94723
94724
94725
94726
94727
94728
94729
94730
94731
94732
/*
** For LIKE and GLOB matching on EBCDIC machines, assume that every
** character is exactly one byte in size.  Also, all characters are
** able to participate in upper-case-to-lower-case mappings in EBCDIC
** whereas only characters less than 0x80 do in ASCII.
*/
#if defined(SQLITE_EBCDIC)
# define sqlite3Utf8Read(A)    (*((*A)++))
# define GlobUpperToLower(A)   A = sqlite3UpperToLower[A]

#else
# define GlobUpperToLower(A)   if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }

#endif

static const struct compareInfo globInfo = { '*', '?', '[', 0 };
/* The correct SQL-92 behavior is for the LIKE operator to ignore
** case.  Thus  'a' LIKE 'A' would be true. */
static const struct compareInfo likeInfoNorm = { '%', '_',   0, 1 };
/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
** is case sensitive causing 'a' LIKE 'A' to be false */
static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };

/*
** Compare two UTF-8 strings for equality where the first string can
** potentially be a "glob" expression.  Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
**      '*'       Matches any sequence of zero or more characters.
**
**      '?'       Matches exactly one character.
**
**     [...]      Matches one character from the enclosed list of
**                characters.
**
**     [^...]     Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'.  A
** range of characters can be specified using '-'.  Example:
** "[a-z]" matches any single lower-case letter.  To match a '-', make
** it the last character in the list.
**
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]".  Like this:
**
**         abc[*]xyz        Matches "abc*xyz" only







*/
static int patternCompare(
  const u8 *zPattern,              /* The glob pattern */
  const u8 *zString,               /* The string to compare against the glob */
  const struct compareInfo *pInfo, /* Information about how to do the compare */
  u32 esc                          /* The escape character */
){
  u32 c, c2;
  int invert;
  int seen;
  u8 matchOne = pInfo->matchOne;
  u8 matchAll = pInfo->matchAll;
  u8 matchSet = pInfo->matchSet;
  u8 noCase = pInfo->noCase; 

  int prevEscape = 0;     /* True if the previous character was 'escape' */







  while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
    if( c==matchAll && !prevEscape ){



      while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
               || c == matchOne ){
        if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
          return 0;
        }
      }
      if( c==0 ){
        return 1;
      }else if( c==esc ){

        c = sqlite3Utf8Read(&zPattern);
        if( c==0 ){
          return 0;
        }
      }else if( c==matchSet ){
        assert( esc==0 );         /* This is GLOB, not LIKE */
        assert( matchSet<0x80 );  /* '[' is a single-byte character */

        while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
          SQLITE_SKIP_UTF8(zString);
        }
        return *zString!=0;
      }

      while( (c2 = sqlite3Utf8Read(&zString))!=0 ){









        if( noCase ){
          GlobUpperToLower(c2);
          GlobUpperToLower(c);
          while( c2 != 0 && c2 != c ){

            c2 = sqlite3Utf8Read(&zString);
            GlobUpperToLower(c2);
          }
        }else{
          while( c2 != 0 && c2 != c ){
            c2 = sqlite3Utf8Read(&zString);
          }



        }


        if( c2==0 ) return 0;
        if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
      }

      return 0;

    }else if( c==matchOne && !prevEscape ){

      if( sqlite3Utf8Read(&zString)==0 ){
        return 0;

      }
    }else if( c==matchSet ){
      u32 prior_c = 0;
      assert( esc==0 );    /* This only occurs for GLOB, not LIKE */
      seen = 0;
      invert = 0;
      c = sqlite3Utf8Read(&zString);
      if( c==0 ) return 0;
      c2 = sqlite3Utf8Read(&zPattern);
      if( c2=='^' ){
        invert = 1;
        c2 = sqlite3Utf8Read(&zPattern);
      }
      if( c2==']' ){
        if( c==']' ) seen = 1;
        c2 = sqlite3Utf8Read(&zPattern);
      }
      while( c2 && c2!=']' ){
        if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
          c2 = sqlite3Utf8Read(&zPattern);
          if( c>=prior_c && c<=c2 ) seen = 1;
          prior_c = 0;
        }else{
          if( c==c2 ){
            seen = 1;
          }
          prior_c = c2;
        }
        c2 = sqlite3Utf8Read(&zPattern);
      }
      if( c2==0 || (seen ^ invert)==0 ){
        return 0;
      }
    }else if( esc==c && !prevEscape ){
      prevEscape = 1;
    }else{


      c2 = sqlite3Utf8Read(&zString);
      if( noCase ){
        GlobUpperToLower(c);
        GlobUpperToLower(c2);
      }
      if( c!=c2 ){
        return 0;
      }
      prevEscape = 0;
    }
  }
  return *zString==0;
}

/*
** The sqlite3_strglob() interface.
*/







|
|
>

|
>












|



















|
|
|

|
>
>
>
>
>
>
>







|
<
<
|
|
|
|
>
|
>
>
>
>
>
>


|
>
>
>







|
|
>
|
|
<
|
|
|
|
>
|
|
|
|
|
>
|
>
>
>
>
>
>
>
>
>
|
<
<
|
>
|
|
<

|
<
|
>
>
>

>
>
|
|
|
>

>
|
>
|
|
>
|
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
>
>
|
|
|
|
|
|
|
<
<
<







95679
95680
95681
95682
95683
95684
95685
95686
95687
95688
95689
95690
95691
95692
95693
95694
95695
95696
95697
95698
95699
95700
95701
95702
95703
95704
95705
95706
95707
95708
95709
95710
95711
95712
95713
95714
95715
95716
95717
95718
95719
95720
95721
95722
95723
95724
95725
95726
95727
95728
95729
95730
95731
95732
95733
95734
95735
95736
95737
95738
95739
95740
95741
95742
95743


95744
95745
95746
95747
95748
95749
95750
95751
95752
95753
95754
95755
95756
95757
95758
95759
95760
95761
95762
95763
95764
95765
95766
95767
95768
95769
95770
95771
95772
95773

95774
95775
95776
95777
95778
95779
95780
95781
95782
95783
95784
95785
95786
95787
95788
95789
95790
95791
95792
95793
95794
95795


95796
95797
95798
95799

95800
95801

95802
95803
95804
95805
95806
95807
95808
95809
95810
95811
95812
95813
95814
95815
95816
95817
95818
95819
95820

95821

95822
95823
95824
95825
95826
95827
95828
95829
95830
95831
95832
95833
95834
95835
95836
95837
95838
95839
95840
95841
95842
95843
95844
95845
95846
95847
95848
95849
95850


95851
95852
95853
95854
95855
95856
95857
95858
95859
95860



95861
95862
95863
95864
95865
95866
95867
/*
** For LIKE and GLOB matching on EBCDIC machines, assume that every
** character is exactly one byte in size.  Also, all characters are
** able to participate in upper-case-to-lower-case mappings in EBCDIC
** whereas only characters less than 0x80 do in ASCII.
*/
#if defined(SQLITE_EBCDIC)
# define sqlite3Utf8Read(A)        (*((*A)++))
# define GlobUpperToLower(A)       A = sqlite3UpperToLower[A]
# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
#else
# define GlobUpperToLower(A)       if( A<=0x7f ){ A = sqlite3UpperToLower[A]; }
# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
#endif

static const struct compareInfo globInfo = { '*', '?', '[', 0 };
/* The correct SQL-92 behavior is for the LIKE operator to ignore
** case.  Thus  'a' LIKE 'A' would be true. */
static const struct compareInfo likeInfoNorm = { '%', '_',   0, 1 };
/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
** is case sensitive causing 'a' LIKE 'A' to be false */
static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };

/*
** Compare two UTF-8 strings for equality where the first string can
** potentially be a "glob" or "like" expression.  Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
**      '*'       Matches any sequence of zero or more characters.
**
**      '?'       Matches exactly one character.
**
**     [...]      Matches one character from the enclosed list of
**                characters.
**
**     [^...]     Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'.  A
** range of characters can be specified using '-'.  Example:
** "[a-z]" matches any single lower-case letter.  To match a '-', make
** it the last character in the list.
**
** Like matching rules:
** 
**      '%'       Matches any sequence of zero or more characters
**
***     '_'       Matches any one character
**
**      Ec        Where E is the "esc" character and c is any other
**                character, including '%', '_', and esc, match exactly c.
**
** The comments through this routine usually assume glob matching.
**
** This routine is usually quick, but can be N**2 in the worst case.
*/
static int patternCompare(
  const u8 *zPattern,              /* The glob pattern */
  const u8 *zString,               /* The string to compare against the glob */
  const struct compareInfo *pInfo, /* Information about how to do the compare */
  u32 esc                          /* The escape character */
){
  u32 c, c2;                       /* Next pattern and input string chars */


  u32 matchOne = pInfo->matchOne;  /* "?" or "_" */
  u32 matchAll = pInfo->matchAll;  /* "*" or "%" */
  u32 matchOther;                  /* "[" or the escape character */
  u8 noCase = pInfo->noCase;       /* True if uppercase==lowercase */
  const u8 *zEscaped = 0;          /* One past the last escaped input char */
  
  /* The GLOB operator does not have an ESCAPE clause.  And LIKE does not
  ** have the matchSet operator.  So we either have to look for one or
  ** the other, never both.  Hence the single variable matchOther is used
  ** to store the one we have to look for.
  */
  matchOther = esc ? esc : pInfo->matchSet;

  while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
    if( c==matchAll ){  /* Match "*" */
      /* Skip over multiple "*" characters in the pattern.  If there
      ** are also "?" characters, skip those as well, but consume a
      ** single character of the input string for each "?" skipped */
      while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
               || c == matchOne ){
        if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
          return 0;
        }
      }
      if( c==0 ){
        return 1;   /* "*" at the end of the pattern matches */
      }else if( c==matchOther ){
        if( esc ){
          c = sqlite3Utf8Read(&zPattern);
          if( c==0 ) return 0;

        }else{
          /* "[...]" immediately follows the "*".  We have to do a slow
          ** recursive search in this case, but it is an unusual case. */
          assert( matchOther<0x80 );  /* '[' is a single-byte character */
          while( *zString
                 && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
            SQLITE_SKIP_UTF8(zString);
          }
          return *zString!=0;
        }
      }

      /* At this point variable c contains the first character of the
      ** pattern string past the "*".  Search in the input string for the
      ** first matching character and recursively contine the match from
      ** that point.
      **
      ** For a case-insensitive search, set variable cx to be the same as
      ** c but in the other case and search the input string for either
      ** c or cx.
      */
      if( c<=0x80 ){


        u32 cx;
        if( noCase ){
          cx = sqlite3Toupper(c);
          c = sqlite3Tolower(c);

        }else{
          cx = c;

        }
        while( (c2 = *(zString++))!=0 ){
          if( c2!=c && c2!=cx ) continue;
          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
        }
      }else{
        while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
          if( c2!=c ) continue;
          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
        }
      }
      return 0;
    }
    if( c==matchOther ){
      if( esc ){
        c = sqlite3Utf8Read(&zPattern);
        if( c==0 ) return 0;
        zEscaped = zPattern;
      }else{

        u32 prior_c = 0;

        int seen = 0;
        int invert = 0;
        c = sqlite3Utf8Read(&zString);
        if( c==0 ) return 0;
        c2 = sqlite3Utf8Read(&zPattern);
        if( c2=='^' ){
          invert = 1;
          c2 = sqlite3Utf8Read(&zPattern);
        }
        if( c2==']' ){
          if( c==']' ) seen = 1;
          c2 = sqlite3Utf8Read(&zPattern);
        }
        while( c2 && c2!=']' ){
          if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
            c2 = sqlite3Utf8Read(&zPattern);
            if( c>=prior_c && c<=c2 ) seen = 1;
            prior_c = 0;
          }else{
            if( c==c2 ){
              seen = 1;
            }
            prior_c = c2;
          }
          c2 = sqlite3Utf8Read(&zPattern);
        }
        if( c2==0 || (seen ^ invert)==0 ){
          return 0;
        }


        continue;
      }
    }
    c2 = sqlite3Utf8Read(&zString);
    if( c==c2 ) continue;
    if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
      continue;
    }
    if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
    return 0;



  }
  return *zString==0;
}

/*
** The sqlite3_strglob() interface.
*/
103690
103691
103692
103693
103694
103695
103696
103697



103698
103699
103700
103701
103702
103703
103704
103705
103706
  int nBytes,               /* Length of zSql in bytes. */
  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
  Vdbe *pOld,               /* VM being reprepared */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  int rc;
  assert( ppStmt!=0 );



  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db) ){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
  if( rc==SQLITE_SCHEMA ){
    sqlite3_finalize(*ppStmt);







|
>
>
>

|







104825
104826
104827
104828
104829
104830
104831
104832
104833
104834
104835
104836
104837
104838
104839
104840
104841
104842
104843
104844
  int nBytes,               /* Length of zSql in bytes. */
  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
  Vdbe *pOld,               /* VM being reprepared */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  int rc;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
  if( rc==SQLITE_SCHEMA ){
    sqlite3_finalize(*ppStmt);
103799
103800
103801
103802
103803
103804
103805

103806

103807
103808
103809
103810
103811
103812
103813
103814
103815
  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
  ** tricky bit is figuring out the pointer to return in *pzTail.
  */
  char *zSql8;
  const char *zTail8 = 0;
  int rc = SQLITE_OK;


  assert( ppStmt );

  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db) ){
    return SQLITE_MISUSE_BKPT;
  }
  if( nBytes>=0 ){
    int sz;
    const char *z = (const char*)zSql;
    for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
    nBytes = sz;







>
|
>

|







104937
104938
104939
104940
104941
104942
104943
104944
104945
104946
104947
104948
104949
104950
104951
104952
104953
104954
104955
  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
  ** tricky bit is figuring out the pointer to return in *pzTail.
  */
  char *zSql8;
  const char *zTail8 = 0;
  int rc = SQLITE_OK;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
    return SQLITE_MISUSE_BKPT;
  }
  if( nBytes>=0 ){
    int sz;
    const char *z = (const char*)zSql;
    for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
    nBytes = sz;
103882
103883
103884
103885
103886
103887
103888














103889
103890
103891
103892
103893
103894
103895
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
*/















/*
** An instance of the following object is used to record information about
** how to process the DISTINCT keyword, to simplify passing that information
** into the selectInnerLoop() routine.
*/
typedef struct DistinctCtx DistinctCtx;







>
>
>
>
>
>
>
>
>
>
>
>
>
>







105022
105023
105024
105025
105026
105027
105028
105029
105030
105031
105032
105033
105034
105035
105036
105037
105038
105039
105040
105041
105042
105043
105044
105045
105046
105047
105048
105049
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
*/

/*
** Trace output macros
*/
#if SELECTTRACE_ENABLED
/***/ int sqlite3SelectTrace = 0;
# define SELECTTRACE(K,P,S,X)  \
  if(sqlite3SelectTrace&(K))   \
    sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",(S)->zSelName,(S)),\
    sqlite3DebugPrintf X
#else
# define SELECTTRACE(K,P,S,X)
#endif


/*
** An instance of the following object is used to record information about
** how to process the DISTINCT keyword, to simplify passing that information
** into the selectInnerLoop() routine.
*/
typedef struct DistinctCtx DistinctCtx;
103994
103995
103996
103997
103998
103999
104000












104001
104002
104003
104004
104005
104006
104007
    pNew = 0;
  }else{
    assert( pNew->pSrc!=0 || pParse->nErr>0 );
  }
  assert( pNew!=&standin );
  return pNew;
}













/*
** Delete the given Select structure and all of its substructures.
*/
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
  if( p ){
    clearSelect(db, p);







>
>
>
>
>
>
>
>
>
>
>
>







105148
105149
105150
105151
105152
105153
105154
105155
105156
105157
105158
105159
105160
105161
105162
105163
105164
105165
105166
105167
105168
105169
105170
105171
105172
105173
    pNew = 0;
  }else{
    assert( pNew->pSrc!=0 || pParse->nErr>0 );
  }
  assert( pNew!=&standin );
  return pNew;
}

#if SELECTTRACE_ENABLED
/*
** Set the name of a Select object
*/
SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
  if( p && zName ){
    sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
  }
}
#endif


/*
** Delete the given Select structure and all of its substructures.
*/
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
  if( p ){
    clearSelect(db, p);
105024
105025
105026
105027
105028
105029
105030
105031
105032
105033
105034
105035
105036
105037
105038
  int eDest = pDest->eDest;
  int iParm = pDest->iSDParm;
  int regRow;
  int regRowid;
  int nKey;
  int iSortTab;                   /* Sorter cursor to read from */
  int nSortData;                  /* Trailing values to read from sorter */
  u8 p5;                          /* p5 parameter for 1st OP_Column */
  int i;
  int bSeq;                       /* True if sorter record includes seq. no. */
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  struct ExprList_item *aOutEx = p->pEList->a;
#endif

  if( pSort->labelBkOut ){







<







106190
106191
106192
106193
106194
106195
106196

106197
106198
106199
106200
106201
106202
106203
  int eDest = pDest->eDest;
  int iParm = pDest->iSDParm;
  int regRow;
  int regRowid;
  int nKey;
  int iSortTab;                   /* Sorter cursor to read from */
  int nSortData;                  /* Trailing values to read from sorter */

  int i;
  int bSeq;                       /* True if sorter record includes seq. no. */
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  struct ExprList_item *aOutEx = p->pEList->a;
#endif

  if( pSort->labelBkOut ){
105058
105059
105060
105061
105062
105063
105064
105065
105066
105067
105068
105069
105070
105071
105072
105073
105074
105075
105076
105077
105078
105079
105080
105081
105082
105083
105084
      addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
    }
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
    if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
    addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
    VdbeCoverage(v);
    codeOffset(v, p->iOffset, addrContinue);
    sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
    p5 = OPFLAG_CLEARCACHE;
    bSeq = 0;
  }else{
    addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
    codeOffset(v, p->iOffset, addrContinue);
    iSortTab = iTab;
    p5 = 0;
    bSeq = 1;
  }
  for(i=0; i<nSortData; i++){
    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
    if( i==0 ) sqlite3VdbeChangeP5(v, p5);
    VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );







|
<





<




<







106223
106224
106225
106226
106227
106228
106229
106230

106231
106232
106233
106234
106235

106236
106237
106238
106239

106240
106241
106242
106243
106244
106245
106246
      addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
    }
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
    if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
    addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
    VdbeCoverage(v);
    codeOffset(v, p->iOffset, addrContinue);
    sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);

    bSeq = 0;
  }else{
    addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
    codeOffset(v, p->iOffset, addrContinue);
    iSortTab = iTab;

    bSeq = 1;
  }
  for(i=0; i<nSortData; i++){
    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);

    VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
107224
107225
107226
107227
107228
107229
107230


107231
107232
107233
107234
107235
107236
107237
      for(ii=0; ii<p->pOrderBy->nExpr; ii++){
        if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
      }
    }
  }

  /***** If we reach this point, flattening is permitted. *****/



  /* Authorize the subquery */
  pParse->zAuthContext = pSubitem->zName;
  TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
  testcase( i==SQLITE_DENY );
  pParse->zAuthContext = zSavedAuthContext;








>
>







108386
108387
108388
108389
108390
108391
108392
108393
108394
108395
108396
108397
108398
108399
108400
108401
      for(ii=0; ii<p->pOrderBy->nExpr; ii++){
        if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
      }
    }
  }

  /***** If we reach this point, flattening is permitted. *****/
  SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
                   pSub->zSelName, pSub, iFrom));

  /* Authorize the subquery */
  pParse->zAuthContext = pSubitem->zName;
  TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
  testcase( i==SQLITE_DENY );
  pParse->zAuthContext = zSavedAuthContext;

107276
107277
107278
107279
107280
107281
107282

107283
107284
107285
107286
107287
107288
107289
107290
107291
107292
107293
107294



107295
107296
107297
107298
107299
107300
107301
    Select *pPrior = p->pPrior;
    p->pOrderBy = 0;
    p->pSrc = 0;
    p->pPrior = 0;
    p->pLimit = 0;
    p->pOffset = 0;
    pNew = sqlite3SelectDup(db, p, 0);

    p->pOffset = pOffset;
    p->pLimit = pLimit;
    p->pOrderBy = pOrderBy;
    p->pSrc = pSrc;
    p->op = TK_ALL;
    if( pNew==0 ){
      p->pPrior = pPrior;
    }else{
      pNew->pPrior = pPrior;
      if( pPrior ) pPrior->pNext = pNew;
      pNew->pNext = p;
      p->pPrior = pNew;



    }
    if( db->mallocFailed ) return 1;
  }

  /* Begin flattening the iFrom-th entry of the FROM clause 
  ** in the outer query.
  */







>












>
>
>







108440
108441
108442
108443
108444
108445
108446
108447
108448
108449
108450
108451
108452
108453
108454
108455
108456
108457
108458
108459
108460
108461
108462
108463
108464
108465
108466
108467
108468
108469
    Select *pPrior = p->pPrior;
    p->pOrderBy = 0;
    p->pSrc = 0;
    p->pPrior = 0;
    p->pLimit = 0;
    p->pOffset = 0;
    pNew = sqlite3SelectDup(db, p, 0);
    sqlite3SelectSetName(pNew, pSub->zSelName);
    p->pOffset = pOffset;
    p->pLimit = pLimit;
    p->pOrderBy = pOrderBy;
    p->pSrc = pSrc;
    p->op = TK_ALL;
    if( pNew==0 ){
      p->pPrior = pPrior;
    }else{
      pNew->pPrior = pPrior;
      if( pPrior ) pPrior->pNext = pNew;
      pNew->pNext = p;
      p->pPrior = pNew;
      SELECTTRACE(2,pParse,p,
         ("compound-subquery flattener creates %s.%p as peer\n",
         pNew->zSelName, pNew));
    }
    if( db->mallocFailed ) return 1;
  }

  /* Begin flattening the iFrom-th entry of the FROM clause 
  ** in the outer query.
  */
107417
107418
107419
107420
107421
107422
107423














107424

107425
107426
107427
107428
107429
107430
107431
107432
    }
    substExprList(db, pParent->pEList, iParent, pSub->pEList);
    if( isAgg ){
      substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
    }
    if( pSub->pOrderBy ){














      assert( pParent->pOrderBy==0 );

      pParent->pOrderBy = pSub->pOrderBy;
      pSub->pOrderBy = 0;
    }else if( pParent->pOrderBy ){
      substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
    }
    if( pSub->pWhere ){
      pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
    }else{







>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
|







108585
108586
108587
108588
108589
108590
108591
108592
108593
108594
108595
108596
108597
108598
108599
108600
108601
108602
108603
108604
108605
108606
108607
108608
108609
108610
108611
108612
108613
108614
108615
    }
    substExprList(db, pParent->pEList, iParent, pSub->pEList);
    if( isAgg ){
      substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
    }
    if( pSub->pOrderBy ){
      /* At this point, any non-zero iOrderByCol values indicate that the
      ** ORDER BY column expression is identical to the iOrderByCol'th
      ** expression returned by SELECT statement pSub. Since these values
      ** do not necessarily correspond to columns in SELECT statement pParent,
      ** zero them before transfering the ORDER BY clause.
      **
      ** Not doing this may cause an error if a subsequent call to this
      ** function attempts to flatten a compound sub-query into pParent
      ** (the only way this can happen is if the compound sub-query is
      ** currently part of pSub->pSrc). See ticket [d11a6e908f].  */
      ExprList *pOrderBy = pSub->pOrderBy;
      for(i=0; i<pOrderBy->nExpr; i++){
        pOrderBy->a[i].u.x.iOrderByCol = 0;
      }
      assert( pParent->pOrderBy==0 );
      assert( pSub->pPrior==0 );
      pParent->pOrderBy = pOrderBy;
      pSub->pOrderBy = 0;
    }else if( pParent->pOrderBy ){
      substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
    }
    if( pSub->pWhere ){
      pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
    }else{
107463
107464
107465
107466
107467
107468
107469







107470
107471
107472
107473
107474
107475
107476
    }
  }

  /* Finially, delete what is left of the subquery and return
  ** success.
  */
  sqlite3SelectDelete(db, pSub1);








  return 1;
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

/*
** Based on the contents of the AggInfo structure indicated by the first







>
>
>
>
>
>
>







108646
108647
108648
108649
108650
108651
108652
108653
108654
108655
108656
108657
108658
108659
108660
108661
108662
108663
108664
108665
108666
    }
  }

  /* Finially, delete what is left of the subquery and return
  ** success.
  */
  sqlite3SelectDelete(db, pSub1);

#if SELECTTRACE_ENABLED
  if( sqlite3SelectTrace & 0x100 ){
    sqlite3DebugPrintf("After flattening:\n");
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  return 1;
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

/*
** Based on the contents of the AggInfo structure indicated by the first
107934
107935
107936
107937
107938
107939
107940

107941
107942
107943
107944
107945
107946
107947
      pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
      if( pTab->pSelect || IsVirtual(pTab) ){
        /* We reach here if the named table is a really a view */
        if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
        assert( pFrom->pSelect==0 );
        pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);

        sqlite3WalkSelect(pWalker, pFrom->pSelect);
      }
#endif
    }

    /* Locate the index named by the INDEXED BY clause, if any. */
    if( sqlite3IndexedByLookup(pParse, pFrom) ){







>







109124
109125
109126
109127
109128
109129
109130
109131
109132
109133
109134
109135
109136
109137
109138
      pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
      if( pTab->pSelect || IsVirtual(pTab) ){
        /* We reach here if the named table is a really a view */
        if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
        assert( pFrom->pSelect==0 );
        pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
        sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
        sqlite3WalkSelect(pWalker, pFrom->pSelect);
      }
#endif
    }

    /* Locate the index named by the INDEXED BY clause, if any. */
    if( sqlite3IndexedByLookup(pParse, pFrom) ){
108468
108469
108470
108471
108472
108473
108474







108475
108476
108477
108478
108479
108480
108481

  db = pParse->db;
  if( p==0 || db->mallocFailed || pParse->nErr ){
    return 1;
  }
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  memset(&sAggInfo, 0, sizeof(sAggInfo));








  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
  if( IgnorableOrderby(pDest) ){
    assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || 







>
>
>
>
>
>
>







109659
109660
109661
109662
109663
109664
109665
109666
109667
109668
109669
109670
109671
109672
109673
109674
109675
109676
109677
109678
109679

  db = pParse->db;
  if( p==0 || db->mallocFailed || pParse->nErr ){
    return 1;
  }
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  memset(&sAggInfo, 0, sizeof(sAggInfo));
#if SELECTTRACE_ENABLED
  pParse->nSelectIndent++;
  SELECTTRACE(1,pParse,p, ("begin processing:\n"));
  if( sqlite3SelectTrace & 0x100 ){
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
  if( IgnorableOrderby(pDest) ){
    assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || 
108624
108625
108626
108627
108628
108629
108630




108631
108632
108633
108634
108635
108636
108637

#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
    rc = multiSelect(pParse, p, pDest);
    explainSetInteger(pParse->iSelectId, iRestoreSelectId);




    return rc;
  }
#endif

  /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
  ** if the select-list is the same as the ORDER BY list, then this query
  ** can be rewritten as a GROUP BY. In other words, this:







>
>
>
>







109822
109823
109824
109825
109826
109827
109828
109829
109830
109831
109832
109833
109834
109835
109836
109837
109838
109839

#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
    rc = multiSelect(pParse, p, pDest);
    explainSetInteger(pParse->iSelectId, iRestoreSelectId);
#if SELECTTRACE_ENABLED
    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
    pParse->nSelectIndent--;
#endif
    return rc;
  }
#endif

  /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
  ** if the select-list is the same as the ORDER BY list, then this query
  ** can be rewritten as a GROUP BY. In other words, this:
108959
108960
108961
108962
108963
108964
108965
108966
108967
108968
108969
108970
108971
108972
108973
108974
108975
108976
108977
108978
      ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
      ** Then compare the current GROUP BY terms against the GROUP BY terms
      ** from the previous row currently stored in a0, a1, a2...
      */
      addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
      sqlite3ExprCacheClear(pParse);
      if( groupBySort ){
        sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
      }
      for(j=0; j<pGroupBy->nExpr; j++){
        if( groupBySort ){
          sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
          if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
        }else{
          sAggInfo.directMode = 1;
          sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
        }
      }
      sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
                          (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);







|




<







110161
110162
110163
110164
110165
110166
110167
110168
110169
110170
110171
110172

110173
110174
110175
110176
110177
110178
110179
      ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
      ** Then compare the current GROUP BY terms against the GROUP BY terms
      ** from the previous row currently stored in a0, a1, a2...
      */
      addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
      sqlite3ExprCacheClear(pParse);
      if( groupBySort ){
        sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
      }
      for(j=0; j<pGroupBy->nExpr; j++){
        if( groupBySort ){
          sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);

        }else{
          sAggInfo.directMode = 1;
          sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
        }
      }
      sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
                          (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
109223
109224
109225
109226
109227
109228
109229




109230
109231
109232
109233
109234
109235
109236
109237


109238
109239
109240
109241
109242
109243
109244
109245
109246



109247
109248
109249



109250
109251
109252
109253
109254
109255
109256



109257
109258
109259
109260
109261
109262
109263
109264
109265
109266
109267
109268
109269
109270
109271
109272



109273
109274
109275


109276
109277
109278
109279
109280
109281
109282
109283
109284
109285
109286
109287
109288
109289
109290
109291
109292
109293
109294
109295
109296
109297
109298
109299
109300
109301
109302
109303
109304
109305
109306
109307
109308


109309
109310

109311
109312
109313
109314
109315
109316
109317
109318
109319
109320
109321
109322
109323
109324
109325
109326
109327
109328
109329
109330
109331
109332
109333
  */
  if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
    generateColumnNames(pParse, pTabList, pEList);
  }

  sqlite3DbFree(db, sAggInfo.aCol);
  sqlite3DbFree(db, sAggInfo.aFunc);




  return rc;
}

#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Generate a human-readable description of a the Select object.
*/
static void explainOneSelect(Vdbe *pVdbe, Select *p){


  sqlite3ExplainPrintf(pVdbe, "SELECT ");
  if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
    if( p->selFlags & SF_Distinct ){
      sqlite3ExplainPrintf(pVdbe, "DISTINCT ");
    }
    if( p->selFlags & SF_Aggregate ){
      sqlite3ExplainPrintf(pVdbe, "agg_flag ");
    }
    sqlite3ExplainNL(pVdbe);



    sqlite3ExplainPrintf(pVdbe, "   ");
  }
  sqlite3ExplainExprList(pVdbe, p->pEList);



  sqlite3ExplainNL(pVdbe);
  if( p->pSrc && p->pSrc->nSrc ){
    int i;
    sqlite3ExplainPrintf(pVdbe, "FROM ");
    sqlite3ExplainPush(pVdbe);
    for(i=0; i<p->pSrc->nSrc; i++){
      struct SrcList_item *pItem = &p->pSrc->a[i];



      sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
      if( pItem->pSelect ){
        sqlite3ExplainSelect(pVdbe, pItem->pSelect);
        if( pItem->pTab ){
          sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
        }
      }else if( pItem->zName ){
        sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName);
      }
      if( pItem->zAlias ){
        sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
      }
      if( pItem->jointype & JT_LEFT ){
        sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN");
      }
      sqlite3ExplainNL(pVdbe);



    }
    sqlite3ExplainPop(pVdbe);
  }


  if( p->pWhere ){
    sqlite3ExplainPrintf(pVdbe, "WHERE ");
    sqlite3ExplainExpr(pVdbe, p->pWhere);
    sqlite3ExplainNL(pVdbe);
  }
  if( p->pGroupBy ){
    sqlite3ExplainPrintf(pVdbe, "GROUPBY ");
    sqlite3ExplainExprList(pVdbe, p->pGroupBy);
    sqlite3ExplainNL(pVdbe);
  }
  if( p->pHaving ){
    sqlite3ExplainPrintf(pVdbe, "HAVING ");
    sqlite3ExplainExpr(pVdbe, p->pHaving);
    sqlite3ExplainNL(pVdbe);
  }
  if( p->pOrderBy ){
    sqlite3ExplainPrintf(pVdbe, "ORDERBY ");
    sqlite3ExplainExprList(pVdbe, p->pOrderBy);
    sqlite3ExplainNL(pVdbe);
  }
  if( p->pLimit ){
    sqlite3ExplainPrintf(pVdbe, "LIMIT ");
    sqlite3ExplainExpr(pVdbe, p->pLimit);
    sqlite3ExplainNL(pVdbe);
  }
  if( p->pOffset ){
    sqlite3ExplainPrintf(pVdbe, "OFFSET ");
    sqlite3ExplainExpr(pVdbe, p->pOffset);
    sqlite3ExplainNL(pVdbe);
  }
}
SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
  if( p==0 ){


    sqlite3ExplainPrintf(pVdbe, "(null-select)");
    return;

  }
  sqlite3ExplainPush(pVdbe);
  while( p ){
    explainOneSelect(pVdbe, p);
    p = p->pNext;
    if( p==0 ) break;
    sqlite3ExplainNL(pVdbe);
    sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
  }
  sqlite3ExplainPrintf(pVdbe, "END");
  sqlite3ExplainPop(pVdbe);
}

/* End of the structure debug printing code
*****************************************************************************/
#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */

/************** End of select.c **********************************************/
/************** Begin file table.c *******************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of







>
>
>
>



|



|
>
>
|
<
|
<
<
|
<
<
|
>
>
>
|
<
|
>
>
>
|


|
|


>
>
>
|
|
|
|
|
|
|
|


|


|

|
>
>
>
|
|
|
>
>

|
|
|


<
|
<


|
|
|


<
|
<


|
|
|


|
|
|

<
<
|
>
>
|
|
>
|
|
<
|
<
<
|
<

<
|

|
<
<
<







110424
110425
110426
110427
110428
110429
110430
110431
110432
110433
110434
110435
110436
110437
110438
110439
110440
110441
110442
110443
110444
110445

110446


110447


110448
110449
110450
110451
110452

110453
110454
110455
110456
110457
110458
110459
110460
110461
110462
110463
110464
110465
110466
110467
110468
110469
110470
110471
110472
110473
110474
110475
110476
110477
110478
110479
110480
110481
110482
110483
110484
110485
110486
110487
110488
110489
110490
110491
110492
110493
110494
110495
110496

110497

110498
110499
110500
110501
110502
110503
110504

110505

110506
110507
110508
110509
110510
110511
110512
110513
110514
110515
110516


110517
110518
110519
110520
110521
110522
110523
110524

110525


110526

110527

110528
110529
110530



110531
110532
110533
110534
110535
110536
110537
  */
  if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
    generateColumnNames(pParse, pTabList, pEList);
  }

  sqlite3DbFree(db, sAggInfo.aCol);
  sqlite3DbFree(db, sAggInfo.aFunc);
#if SELECTTRACE_ENABLED
  SELECTTRACE(1,pParse,p,("end processing\n"));
  pParse->nSelectIndent--;
#endif
  return rc;
}

#ifdef SQLITE_DEBUG
/*
** Generate a human-readable description of a the Select object.
*/
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
  int n = 0;
  pView = sqlite3TreeViewPush(pView, moreToFollow);
  sqlite3TreeViewLine(pView, "SELECT%s%s",

    ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),


    ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")


  );
  if( p->pSrc && p->pSrc->nSrc ) n++;
  if( p->pWhere ) n++;
  if( p->pGroupBy ) n++;
  if( p->pHaving ) n++;

  if( p->pOrderBy ) n++;
  if( p->pLimit ) n++;
  if( p->pOffset ) n++;
  if( p->pPrior ) n++;
  sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
  if( p->pSrc && p->pSrc->nSrc ){
    int i;
    pView = sqlite3TreeViewPush(pView, (n--)>0);
    sqlite3TreeViewLine(pView, "FROM");
    for(i=0; i<p->pSrc->nSrc; i++){
      struct SrcList_item *pItem = &p->pSrc->a[i];
      StrAccum x;
      char zLine[100];
      sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
      sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
      if( pItem->zDatabase ){
        sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
      }else if( pItem->zName ){
        sqlite3XPrintf(&x, 0, " %s", pItem->zName);
      }
      if( pItem->pTab ){
        sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
      }
      if( pItem->zAlias ){
        sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
      }
      if( pItem->jointype & JT_LEFT ){
        sqlite3XPrintf(&x, 0, " LEFT-JOIN");
      }
      sqlite3StrAccumFinish(&x);
      sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
      if( pItem->pSelect ){
        sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
      }
      sqlite3TreeViewPop(pView);
    }
    sqlite3TreeViewPop(pView);
  }
  if( p->pWhere ){
    sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pWhere, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pGroupBy ){

    sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");

  }
  if( p->pHaving ){
    sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pHaving, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pOrderBy ){

    sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");

  }
  if( p->pLimit ){
    sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pLimit, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pOffset ){
    sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pOffset, 0);
    sqlite3TreeViewPop(pView);
  }


  if( p->pPrior ){
    const char *zOp = "UNION";
    switch( p->op ){
      case TK_ALL:         zOp = "UNION ALL";  break;
      case TK_INTERSECT:   zOp = "INTERSECT";  break;
      case TK_EXCEPT:      zOp = "EXCEPT";     break;
    }
    sqlite3TreeViewItem(pView, zOp, (n--)>0);

    sqlite3TreeViewSelect(pView, p->pPrior, 0);


    sqlite3TreeViewPop(pView);

  }

  sqlite3TreeViewPop(pView);
}
#endif /* SQLITE_DEBUG */




/************** End of select.c **********************************************/
/************** Begin file table.c *******************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
109450
109451
109452
109453
109454
109455
109456



109457
109458
109459
109460
109461
109462
109463
  int *pnRow,                 /* Write the number of rows in the result here */
  int *pnColumn,              /* Write the number of columns of result here */
  char **pzErrMsg             /* Write error messages here */
){
  int rc;
  TabResult res;




  *pazResult = 0;
  if( pnColumn ) *pnColumn = 0;
  if( pnRow ) *pnRow = 0;
  if( pzErrMsg ) *pzErrMsg = 0;
  res.zErrMsg = 0;
  res.nRow = 0;
  res.nColumn = 0;







>
>
>







110654
110655
110656
110657
110658
110659
110660
110661
110662
110663
110664
110665
110666
110667
110668
110669
110670
  int *pnRow,                 /* Write the number of rows in the result here */
  int *pnColumn,              /* Write the number of columns of result here */
  char **pzErrMsg             /* Write error messages here */
){
  int rc;
  TabResult res;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( pazResult==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *pazResult = 0;
  if( pnColumn ) *pnColumn = 0;
  if( pnRow ) *pnRow = 0;
  if( pzErrMsg ) *pzErrMsg = 0;
  res.zErrMsg = 0;
  res.nRow = 0;
  res.nColumn = 0;
111075
111076
111077
111078
111079
111080
111081
111082
111083
111084
111085
111086
111087
111088
111089
111090
    }
    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen,
                               0, 0);
  }

  /* Top of the update loop */
  if( okOnePass ){
    if( aToOpen[iDataCur-iBaseCur] ){
      assert( pPk!=0 );
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
      VdbeCoverageNeverTaken(v);
    }
    labelContinue = labelBreak;
    sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
    VdbeCoverageIf(v, pPk==0);
    VdbeCoverageIf(v, pPk!=0);







|
|







112282
112283
112284
112285
112286
112287
112288
112289
112290
112291
112292
112293
112294
112295
112296
112297
    }
    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen,
                               0, 0);
  }

  /* Top of the update loop */
  if( okOnePass ){
    if( aToOpen[iDataCur-iBaseCur] && !isView ){
      assert( pPk );
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
      VdbeCoverageNeverTaken(v);
    }
    labelContinue = labelBreak;
    sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
    VdbeCoverageIf(v, pPk==0);
    VdbeCoverageIf(v, pPk!=0);
111513
111514
111515
111516
111517
111518
111519
111520
111521
111522
111523
111524
111525
111526
111527
** original database is required.  Every page of the database is written
** approximately 3 times:  Once for step (2) and twice for step (3).
** Two writes per page are required in step (3) because the original
** database content must be written into the rollback journal prior to
** overwriting the database with the vacuumed content.
**
** Only 1x temporary space and only 1x writes would be required if
** the copy of step (3) were replace by deleting the original database
** and renaming the transient database as the original.  But that will
** not work if other processes are attached to the original database.
** And a power loss in between deleting the original and renaming the
** transient would cause the database file to appear to be deleted
** following reboot.
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){







|







112720
112721
112722
112723
112724
112725
112726
112727
112728
112729
112730
112731
112732
112733
112734
** original database is required.  Every page of the database is written
** approximately 3 times:  Once for step (2) and twice for step (3).
** Two writes per page are required in step (3) because the original
** database content must be written into the rollback journal prior to
** overwriting the database with the vacuumed content.
**
** Only 1x temporary space and only 1x writes would be required if
** the copy of step (3) were replaced by deleting the original database
** and renaming the transient database as the original.  But that will
** not work if other processes are attached to the original database.
** And a power loss in between deleting the original and renaming the
** transient would cause the database file to appear to be deleted
** following reboot.
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
111871
111872
111873
111874
111875
111876
111877



111878
111879
111880
111881
111882
111883
111884
111885
111886
111887
111888
111889
111890



111891
111892
111893
111894
111895
111896
111897
*/
SQLITE_API int sqlite3_create_module(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
  const sqlite3_module *pModule,  /* The definition of the module */
  void *pAux                      /* Context pointer for xCreate/xConnect */
){



  return createModule(db, zName, pModule, pAux, 0);
}

/*
** External API function used to create a new virtual-table module.
*/
SQLITE_API int sqlite3_create_module_v2(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
  const sqlite3_module *pModule,  /* The definition of the module */
  void *pAux,                     /* Context pointer for xCreate/xConnect */
  void (*xDestroy)(void *)        /* Module destructor function */
){



  return createModule(db, zName, pModule, pAux, xDestroy);
}

/*
** Lock the virtual table so that it cannot be disconnected.
** Locks nest.  Every lock should have a corresponding unlock.
** If an unlock is omitted, resources leaks will occur.  







>
>
>













>
>
>







113078
113079
113080
113081
113082
113083
113084
113085
113086
113087
113088
113089
113090
113091
113092
113093
113094
113095
113096
113097
113098
113099
113100
113101
113102
113103
113104
113105
113106
113107
113108
113109
113110
*/
SQLITE_API int sqlite3_create_module(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
  const sqlite3_module *pModule,  /* The definition of the module */
  void *pAux                      /* Context pointer for xCreate/xConnect */
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  return createModule(db, zName, pModule, pAux, 0);
}

/*
** External API function used to create a new virtual-table module.
*/
SQLITE_API int sqlite3_create_module_v2(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
  const sqlite3_module *pModule,  /* The definition of the module */
  void *pAux,                     /* Context pointer for xCreate/xConnect */
  void (*xDestroy)(void *)        /* Module destructor function */
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  return createModule(db, zName, pModule, pAux, xDestroy);
}

/*
** Lock the virtual table so that it cannot be disconnected.
** Locks nest.  Every lock should have a corresponding unlock.
** If an unlock is omitted, resources leaks will occur.  
112116
112117
112118
112119
112120
112121
112122



112123


112124
112125
112126
112127
112128
112129
112130
  assert( iDb>=0 );

  pTable->tabFlags |= TF_Virtual;
  pTable->nModuleArg = 0;
  addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
  addModuleArgument(db, pTable, 0);
  addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));



  pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);



#ifndef SQLITE_OMIT_AUTHORIZATION
  /* Creating a virtual table invokes the authorization callback twice.
  ** The first invocation, to obtain permission to INSERT a row into the
  ** sqlite_master table, has already been made by sqlite3StartTable().
  ** The second call, to obtain permission to create the table, is made now.
  */







>
>
>
|
>
>







113329
113330
113331
113332
113333
113334
113335
113336
113337
113338
113339
113340
113341
113342
113343
113344
113345
113346
113347
113348
  assert( iDb>=0 );

  pTable->tabFlags |= TF_Virtual;
  pTable->nModuleArg = 0;
  addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
  addModuleArgument(db, pTable, 0);
  addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
  assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
       || (pParse->sNameToken.z==pName1->z && pName2->z==0)
  );
  pParse->sNameToken.n = (int)(
      &pModuleName->z[pModuleName->n] - pParse->sNameToken.z
  );

#ifndef SQLITE_OMIT_AUTHORIZATION
  /* Creating a virtual table invokes the authorization callback twice.
  ** The first invocation, to obtain permission to INSERT a row into the
  ** sqlite_master table, has already been made by sqlite3StartTable().
  ** The second call, to obtain permission to create the table, is made now.
  */
112309
112310
112311
112312
112313
112314
112315

112316
112317
112318
112319
112320
112321
112322
      *pzErr = sqlite3MPrintf(db, "%s", zErr);
      sqlite3_free(zErr);
    }
    sqlite3DbFree(db, pVTable);
  }else if( ALWAYS(pVTable->pVtab) ){
    /* Justification of ALWAYS():  A correct vtab constructor must allocate
    ** the sqlite3_vtab object if successful.  */

    pVTable->pVtab->pModule = pMod->pModule;
    pVTable->nRef = 1;
    if( sCtx.pTab ){
      const char *zFormat = "vtable constructor did not declare schema: %s";
      *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
      sqlite3VtabUnlock(pVTable);
      rc = SQLITE_ERROR;







>







113527
113528
113529
113530
113531
113532
113533
113534
113535
113536
113537
113538
113539
113540
113541
      *pzErr = sqlite3MPrintf(db, "%s", zErr);
      sqlite3_free(zErr);
    }
    sqlite3DbFree(db, pVTable);
  }else if( ALWAYS(pVTable->pVtab) ){
    /* Justification of ALWAYS():  A correct vtab constructor must allocate
    ** the sqlite3_vtab object if successful.  */
    memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
    pVTable->pVtab->pModule = pMod->pModule;
    pVTable->nRef = 1;
    if( sCtx.pTab ){
      const char *zFormat = "vtable constructor did not declare schema: %s";
      *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
      sqlite3VtabUnlock(pVTable);
      rc = SQLITE_ERROR;
112487
112488
112489
112490
112491
112492
112493



112494
112495
112496
112497
112498
112499
112500
SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
  Parse *pParse;

  int rc = SQLITE_OK;
  Table *pTab;
  char *zErr = 0;




  sqlite3_mutex_enter(db->mutex);
  if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
    sqlite3Error(db, SQLITE_MISUSE);
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_MISUSE_BKPT;
  }
  assert( (pTab->tabFlags & TF_Virtual)!=0 );







>
>
>







113706
113707
113708
113709
113710
113711
113712
113713
113714
113715
113716
113717
113718
113719
113720
113721
113722
SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
  Parse *pParse;

  int rc = SQLITE_OK;
  Table *pTab;
  char *zErr = 0;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
    sqlite3Error(db, SQLITE_MISUSE);
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_MISUSE_BKPT;
  }
  assert( (pTab->tabFlags & TF_Virtual)!=0 );
112843
112844
112845
112846
112847
112848
112849



112850
112851
112852
112853
112854
112855
112856
112857
112858
112859
112860
112861
112862
112863
112864



112865
112866
112867
112868
112869
112870
112871
112872
112873
** The results of this routine are undefined unless it is called from
** within an xUpdate method.
*/
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
  static const unsigned char aMap[] = { 
    SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE 
  };



  assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
  assert( OE_Ignore==4 && OE_Replace==5 );
  assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
  return (int)aMap[db->vtabOnConflict-1];
}

/*
** Call from within the xCreate() or xConnect() methods to provide 
** the SQLite core with additional information about the behavior
** of the virtual table being implemented.
*/
SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
  va_list ap;
  int rc = SQLITE_OK;




  sqlite3_mutex_enter(db->mutex);

  va_start(ap, op);
  switch( op ){
    case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
      VtabCtx *p = db->pVtabCtx;
      if( !p ){
        rc = SQLITE_MISUSE_BKPT;
      }else{







>
>
>















>
>
>

<







114065
114066
114067
114068
114069
114070
114071
114072
114073
114074
114075
114076
114077
114078
114079
114080
114081
114082
114083
114084
114085
114086
114087
114088
114089
114090
114091
114092
114093

114094
114095
114096
114097
114098
114099
114100
** The results of this routine are undefined unless it is called from
** within an xUpdate method.
*/
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
  static const unsigned char aMap[] = { 
    SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE 
  };
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
  assert( OE_Ignore==4 && OE_Replace==5 );
  assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
  return (int)aMap[db->vtabOnConflict-1];
}

/*
** Call from within the xCreate() or xConnect() methods to provide 
** the SQLite core with additional information about the behavior
** of the virtual table being implemented.
*/
SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
  va_list ap;
  int rc = SQLITE_OK;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);

  va_start(ap, op);
  switch( op ){
    case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
      VtabCtx *p = db->pVtabCtx;
      if( !p ){
        rc = SQLITE_MISUSE_BKPT;
      }else{
112994
112995
112996
112997
112998
112999
113000



113001
113002
113003
113004
113005
113006
113007
        u8 eEndLoopOp;         /* IN Loop terminator. OP_Next or OP_Prev */
      } *aInLoop;           /* Information about each nested IN operator */
    } in;                 /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
    Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
  } u;
  struct WhereLoop *pWLoop;  /* The selected WhereLoop object */
  Bitmask notReady;          /* FROM entries not usable at this level */



};

/*
** Each instance of this object represents an algorithm for evaluating one
** term of a join.  Every term of the FROM clause will have at least
** one corresponding WhereLoop object (unless INDEXED BY constraints
** prevent a query solution - which is an error) and many terms of the







>
>
>







114221
114222
114223
114224
114225
114226
114227
114228
114229
114230
114231
114232
114233
114234
114235
114236
114237
        u8 eEndLoopOp;         /* IN Loop terminator. OP_Next or OP_Prev */
      } *aInLoop;           /* Information about each nested IN operator */
    } in;                 /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
    Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
  } u;
  struct WhereLoop *pWLoop;  /* The selected WhereLoop object */
  Bitmask notReady;          /* FROM entries not usable at this level */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  int addrVisit;        /* Address at which row is visited */
#endif
};

/*
** Each instance of this object represents an algorithm for evaluating one
** term of a join.  Every term of the FROM clause will have at least
** one corresponding WhereLoop object (unless INDEXED BY constraints
** prevent a query solution - which is an error) and many terms of the
113024
113025
113026
113027
113028
113029
113030
113031
113032
113033
113034
113035
113036
113037
113038
113039
113040
113041
113042
113043

113044
113045
113046
113047
113048
113049
113050
113051
113052
113053
113054
113055
113056
  u8 iSortIdx;          /* Sorting index number.  0==None */
  LogEst rSetup;        /* One-time setup cost (ex: create transient index) */
  LogEst rRun;          /* Cost of running each loop */
  LogEst nOut;          /* Estimated number of output rows */
  union {
    struct {               /* Information for internal btree tables */
      u16 nEq;               /* Number of equality constraints */
      u16 nSkip;             /* Number of initial index columns to skip */
      Index *pIndex;         /* Index used, or NULL */
    } btree;
    struct {               /* Information for virtual tables */
      int idxNum;            /* Index number */
      u8 needFree;           /* True if sqlite3_free(idxStr) is needed */
      i8 isOrdered;          /* True if satisfies ORDER BY */
      u16 omitMask;          /* Terms that may be omitted */
      char *idxStr;          /* Index identifier string */
    } vtab;
  } u;
  u32 wsFlags;          /* WHERE_* flags describing the plan */
  u16 nLTerm;           /* Number of entries in aLTerm[] */

  /**** whereLoopXfer() copies fields above ***********************/
# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
  u16 nLSlot;           /* Number of slots allocated for aLTerm[] */
  WhereTerm **aLTerm;   /* WhereTerms used */
  WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
  WhereTerm *aLTermSpace[4];  /* Initial aLTerm[] space */
};

/* This object holds the prerequisites and the cost of running a
** subquery on one operand of an OR operator in the WHERE clause.
** See WhereOrSet for additional information 
*/
struct WhereOrCost {







<












>





|







114254
114255
114256
114257
114258
114259
114260

114261
114262
114263
114264
114265
114266
114267
114268
114269
114270
114271
114272
114273
114274
114275
114276
114277
114278
114279
114280
114281
114282
114283
114284
114285
114286
  u8 iSortIdx;          /* Sorting index number.  0==None */
  LogEst rSetup;        /* One-time setup cost (ex: create transient index) */
  LogEst rRun;          /* Cost of running each loop */
  LogEst nOut;          /* Estimated number of output rows */
  union {
    struct {               /* Information for internal btree tables */
      u16 nEq;               /* Number of equality constraints */

      Index *pIndex;         /* Index used, or NULL */
    } btree;
    struct {               /* Information for virtual tables */
      int idxNum;            /* Index number */
      u8 needFree;           /* True if sqlite3_free(idxStr) is needed */
      i8 isOrdered;          /* True if satisfies ORDER BY */
      u16 omitMask;          /* Terms that may be omitted */
      char *idxStr;          /* Index identifier string */
    } vtab;
  } u;
  u32 wsFlags;          /* WHERE_* flags describing the plan */
  u16 nLTerm;           /* Number of entries in aLTerm[] */
  u16 nSkip;            /* Number of NULL aLTerm[] entries */
  /**** whereLoopXfer() copies fields above ***********************/
# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
  u16 nLSlot;           /* Number of slots allocated for aLTerm[] */
  WhereTerm **aLTerm;   /* WhereTerms used */
  WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
  WhereTerm *aLTermSpace[3];  /* Initial aLTerm[] space */
};

/* This object holds the prerequisites and the cost of running a
** subquery on one operand of an OR operator in the WHERE clause.
** See WhereOrSet for additional information 
*/
struct WhereOrCost {
113368
113369
113370
113371
113372
113373
113374

113375
113376
113377
113378
113379
113380
113381
#define WHERE_VIRTUALTABLE 0x00000400  /* WhereLoop.u.vtab is valid */
#define WHERE_IN_ABLE      0x00000800  /* Able to support an IN operator */
#define WHERE_ONEROW       0x00001000  /* Selects no more than one row */
#define WHERE_MULTI_OR     0x00002000  /* OR using multiple indices */
#define WHERE_AUTO_INDEX   0x00004000  /* Uses an ephemeral index */
#define WHERE_SKIPSCAN     0x00008000  /* Uses the skip-scan algorithm */
#define WHERE_UNQ_WANTED   0x00010000  /* WHERE_ONEROW would have been helpful*/


/************** End of whereInt.h ********************************************/
/************** Continuing where we left off in where.c **********************/

/*
** Return the estimated number of output rows from a WHERE clause
*/







>







114598
114599
114600
114601
114602
114603
114604
114605
114606
114607
114608
114609
114610
114611
114612
#define WHERE_VIRTUALTABLE 0x00000400  /* WhereLoop.u.vtab is valid */
#define WHERE_IN_ABLE      0x00000800  /* Able to support an IN operator */
#define WHERE_ONEROW       0x00001000  /* Selects no more than one row */
#define WHERE_MULTI_OR     0x00002000  /* OR using multiple indices */
#define WHERE_AUTO_INDEX   0x00004000  /* Uses an ephemeral index */
#define WHERE_SKIPSCAN     0x00008000  /* Uses the skip-scan algorithm */
#define WHERE_UNQ_WANTED   0x00010000  /* WHERE_ONEROW would have been helpful*/
#define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */

/************** End of whereInt.h ********************************************/
/************** Continuing where we left off in where.c **********************/

/*
** Return the estimated number of output rows from a WHERE clause
*/
113578
113579
113580
113581
113582
113583
113584
113585
113586
113587
113588
113589
113590
113591
113592
    if( pOld!=pWC->aStatic ){
      sqlite3DbFree(db, pOld);
    }
    pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
  }
  pTerm = &pWC->a[idx = pWC->nTerm++];
  if( p && ExprHasProperty(p, EP_Unlikely) ){
    pTerm->truthProb = sqlite3LogEst(p->iTable) - 99;
  }else{
    pTerm->truthProb = 1;
  }
  pTerm->pExpr = sqlite3ExprSkipCollate(p);
  pTerm->wtFlags = wtFlags;
  pTerm->pWC = pWC;
  pTerm->iParent = -1;







|







114809
114810
114811
114812
114813
114814
114815
114816
114817
114818
114819
114820
114821
114822
114823
    if( pOld!=pWC->aStatic ){
      sqlite3DbFree(db, pOld);
    }
    pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
  }
  pTerm = &pWC->a[idx = pWC->nTerm++];
  if( p && ExprHasProperty(p, EP_Unlikely) ){
    pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
  }else{
    pTerm->truthProb = 1;
  }
  pTerm->pExpr = sqlite3ExprSkipCollate(p);
  pTerm->wtFlags = wtFlags;
  pTerm->pWC = pWC;
  pTerm->iParent = -1;
113717
113718
113719
113720
113721
113722
113723
113724
113725
113726
113727
113728
113729
113730
113731
113732
113733
113734
113735
  assert( TK_GT>TK_EQ && TK_GT<TK_GE );
  assert( TK_LT>TK_EQ && TK_LT<TK_GE );
  assert( TK_LE>TK_EQ && TK_LE<TK_GE );
  assert( TK_GE==TK_EQ+4 );
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
}

/*
** Swap two objects of type TYPE.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Commute a comparison operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If left/right precedence rules come into play when determining the
** collating sequence, then COLLATE operators are adjusted to ensure
** that the collating sequence does not change.  For example:







<
<
<
<
<







114948
114949
114950
114951
114952
114953
114954





114955
114956
114957
114958
114959
114960
114961
  assert( TK_GT>TK_EQ && TK_GT<TK_GE );
  assert( TK_LT>TK_EQ && TK_LT<TK_GE );
  assert( TK_LE>TK_EQ && TK_LE<TK_GE );
  assert( TK_GE==TK_EQ+4 );
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
}






/*
** Commute a comparison operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If left/right precedence rules come into play when determining the
** collating sequence, then COLLATE operators are adjusted to ensure
** that the collating sequence does not change.  For example:
114113
114114
114115
114116
114117
114118
114119









114120
114121
114122
114123
114124
114125
114126
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
  if( pDerived ){
    pDerived->flags |= pBase->flags & EP_FromJoin;
    pDerived->iRightJoinTable = pBase->iRightJoinTable;
  }
}










#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Analyze a term that consists of two or more OR-connected
** subterms.  So in:
**
**     ... WHERE  (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13)







>
>
>
>
>
>
>
>
>







115339
115340
115341
115342
115343
115344
115345
115346
115347
115348
115349
115350
115351
115352
115353
115354
115355
115356
115357
115358
115359
115360
115361
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
  if( pDerived ){
    pDerived->flags |= pBase->flags & EP_FromJoin;
    pDerived->iRightJoinTable = pBase->iRightJoinTable;
  }
}

/*
** Mark term iChild as being a child of term iParent
*/
static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){
  pWC->a[iChild].iParent = iParent;
  pWC->a[iChild].truthProb = pWC->a[iParent].truthProb;
  pWC->a[iParent].nChild++;
}

#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Analyze a term that consists of two or more OR-connected
** subterms.  So in:
**
**     ... WHERE  (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13)
114411
114412
114413
114414
114415
114416
114417
114418
114419
114420
114421
114422
114423
114424
114425
114426
        transferJoinMarkings(pNew, pExpr);
        assert( !ExprHasProperty(pNew, EP_xIsSelect) );
        pNew->x.pList = pList;
        idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
        testcase( idxNew==0 );
        exprAnalyze(pSrc, pWC, idxNew);
        pTerm = &pWC->a[idxTerm];
        pWC->a[idxNew].iParent = idxTerm;
        pTerm->nChild = 1;
      }else{
        sqlite3ExprListDelete(db, pList);
      }
      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 2 */
    }
  }
}







|
<







115646
115647
115648
115649
115650
115651
115652
115653

115654
115655
115656
115657
115658
115659
115660
        transferJoinMarkings(pNew, pExpr);
        assert( !ExprHasProperty(pNew, EP_xIsSelect) );
        pNew->x.pList = pList;
        idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
        testcase( idxNew==0 );
        exprAnalyze(pSrc, pWC, idxNew);
        pTerm = &pWC->a[idxTerm];
        markTermAsChild(pWC, idxNew, idxTerm);

      }else{
        sqlite3ExprListDelete(db, pList);
      }
      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 2 */
    }
  }
}
114514
114515
114516
114517
114518
114519
114520
114521
114522
114523
114524
114525
114526
114527
114528
114529
114530
        if( db->mallocFailed ){
          sqlite3ExprDelete(db, pDup);
          return;
        }
        idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
        if( idxNew==0 ) return;
        pNew = &pWC->a[idxNew];
        pNew->iParent = idxTerm;
        pTerm = &pWC->a[idxTerm];
        pTerm->nChild = 1;
        pTerm->wtFlags |= TERM_COPIED;
        if( pExpr->op==TK_EQ
         && !ExprHasProperty(pExpr, EP_FromJoin)
         && OptimizationEnabled(db, SQLITE_Transitive)
        ){
          pTerm->eOperator |= WO_EQUIV;
          eExtraOp = WO_EQUIV;







|

<







115748
115749
115750
115751
115752
115753
115754
115755
115756

115757
115758
115759
115760
115761
115762
115763
        if( db->mallocFailed ){
          sqlite3ExprDelete(db, pDup);
          return;
        }
        idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
        if( idxNew==0 ) return;
        pNew = &pWC->a[idxNew];
        markTermAsChild(pWC, idxNew, idxTerm);
        pTerm = &pWC->a[idxTerm];

        pTerm->wtFlags |= TERM_COPIED;
        if( pExpr->op==TK_EQ
         && !ExprHasProperty(pExpr, EP_FromJoin)
         && OptimizationEnabled(db, SQLITE_Transitive)
        ){
          pTerm->eOperator |= WO_EQUIV;
          eExtraOp = WO_EQUIV;
114573
114574
114575
114576
114577
114578
114579
114580
114581
114582
114583
114584
114585
114586
114587
114588
114589
                             sqlite3ExprDup(db, pExpr->pLeft, 0),
                             sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
      transferJoinMarkings(pNewExpr, pExpr);
      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
      testcase( idxNew==0 );
      exprAnalyze(pSrc, pWC, idxNew);
      pTerm = &pWC->a[idxTerm];
      pWC->a[idxNew].iParent = idxTerm;
    }
    pTerm->nChild = 2;
  }
#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */

#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
  /* Analyze a term that is composed of two or more subterms connected by
  ** an OR operator.
  */







|

<







115806
115807
115808
115809
115810
115811
115812
115813
115814

115815
115816
115817
115818
115819
115820
115821
                             sqlite3ExprDup(db, pExpr->pLeft, 0),
                             sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
      transferJoinMarkings(pNewExpr, pExpr);
      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
      testcase( idxNew==0 );
      exprAnalyze(pSrc, pWC, idxNew);
      pTerm = &pWC->a[idxTerm];
      markTermAsChild(pWC, idxNew, idxTerm);
    }

  }
#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */

#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
  /* Analyze a term that is composed of two or more subterms connected by
  ** an OR operator.
  */
114650
114651
114652
114653
114654
114655
114656
114657
114658
114659
114660
114661
114662
114663
114664
114665
114666
           pStr2, 0);
    transferJoinMarkings(pNewExpr2, pExpr);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      pWC->a[idxNew1].iParent = idxTerm;
      pWC->a[idxNew2].iParent = idxTerm;
      pTerm->nChild = 2;
    }
  }
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */

#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Add a WO_MATCH auxiliary term to the constraint set if the
  ** current expression is of the form:  column MATCH expr.







<
|
|







115882
115883
115884
115885
115886
115887
115888

115889
115890
115891
115892
115893
115894
115895
115896
115897
           pStr2, 0);
    transferJoinMarkings(pNewExpr2, pExpr);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){

      markTermAsChild(pWC, idxNew1, idxTerm);
      markTermAsChild(pWC, idxNew2, idxTerm);
    }
  }
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */

#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Add a WO_MATCH auxiliary term to the constraint set if the
  ** current expression is of the form:  column MATCH expr.
114685
114686
114687
114688
114689
114690
114691
114692
114693
114694
114695
114696
114697
114698
114699
114700
114701
114702
114703
114704
114705
114706
114707
114708
114709
114710
114711
114712
114713
114714
114715
114716
114717
114718
114719
114720
114721
114722
114723
114724
114725
114726
114727
114728
114729
114730
114731
114732
114733
114734
114735
114736
114737
114738
114739
114740
114741
114742
114743
      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
      testcase( idxNew==0 );
      pNewTerm = &pWC->a[idxNew];
      pNewTerm->prereqRight = prereqExpr;
      pNewTerm->leftCursor = pLeft->iTable;
      pNewTerm->u.leftColumn = pLeft->iColumn;
      pNewTerm->eOperator = WO_MATCH;
      pNewTerm->iParent = idxTerm;
      pTerm = &pWC->a[idxTerm];
      pTerm->nChild = 1;
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  /* When sqlite_stat3 histogram data is available an operator of the
  ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
  ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
  ** virtual term of that form.
  **
  ** Note that the virtual term must be tagged with TERM_VNULL.  This
  ** TERM_VNULL tag will suppress the not-null check at the beginning
  ** of the loop.  Without the TERM_VNULL flag, the not-null check at
  ** the start of the loop will prevent any results from being returned.
  */
  if( pExpr->op==TK_NOTNULL
   && pExpr->pLeft->op==TK_COLUMN
   && pExpr->pLeft->iColumn>=0
   && OptimizationEnabled(db, SQLITE_Stat3)
  ){
    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;

    pNewExpr = sqlite3PExpr(pParse, TK_GT,
                            sqlite3ExprDup(db, pLeft, 0),
                            sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);

    idxNew = whereClauseInsert(pWC, pNewExpr,
                              TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
    if( idxNew ){
      pNewTerm = &pWC->a[idxNew];
      pNewTerm->prereqRight = 0;
      pNewTerm->leftCursor = pLeft->iTable;
      pNewTerm->u.leftColumn = pLeft->iColumn;
      pNewTerm->eOperator = WO_GT;
      pNewTerm->iParent = idxTerm;
      pTerm = &pWC->a[idxTerm];
      pTerm->nChild = 1;
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

  /* Prevent ON clause terms of a LEFT JOIN from being used to drive







|

<




















|


















|

<







115916
115917
115918
115919
115920
115921
115922
115923
115924

115925
115926
115927
115928
115929
115930
115931
115932
115933
115934
115935
115936
115937
115938
115939
115940
115941
115942
115943
115944
115945
115946
115947
115948
115949
115950
115951
115952
115953
115954
115955
115956
115957
115958
115959
115960
115961
115962
115963
115964
115965

115966
115967
115968
115969
115970
115971
115972
      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
      testcase( idxNew==0 );
      pNewTerm = &pWC->a[idxNew];
      pNewTerm->prereqRight = prereqExpr;
      pNewTerm->leftCursor = pLeft->iTable;
      pNewTerm->u.leftColumn = pLeft->iColumn;
      pNewTerm->eOperator = WO_MATCH;
      markTermAsChild(pWC, idxNew, idxTerm);
      pTerm = &pWC->a[idxTerm];

      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  /* When sqlite_stat3 histogram data is available an operator of the
  ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
  ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
  ** virtual term of that form.
  **
  ** Note that the virtual term must be tagged with TERM_VNULL.  This
  ** TERM_VNULL tag will suppress the not-null check at the beginning
  ** of the loop.  Without the TERM_VNULL flag, the not-null check at
  ** the start of the loop will prevent any results from being returned.
  */
  if( pExpr->op==TK_NOTNULL
   && pExpr->pLeft->op==TK_COLUMN
   && pExpr->pLeft->iColumn>=0
   && OptimizationEnabled(db, SQLITE_Stat34)
  ){
    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;

    pNewExpr = sqlite3PExpr(pParse, TK_GT,
                            sqlite3ExprDup(db, pLeft, 0),
                            sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);

    idxNew = whereClauseInsert(pWC, pNewExpr,
                              TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
    if( idxNew ){
      pNewTerm = &pWC->a[idxNew];
      pNewTerm->prereqRight = 0;
      pNewTerm->leftCursor = pLeft->iTable;
      pNewTerm->u.leftColumn = pLeft->iColumn;
      pNewTerm->eOperator = WO_GT;
      markTermAsChild(pWC, idxNew, idxTerm);
      pTerm = &pWC->a[idxTerm];

      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
114949
114950
114951
114952
114953
114954
114955


114956
114957
114958
114959
114960
114961
114962
114963
114964
114965
114966
114967
114968
114969
114970






114971
114972
114973
114974
114975
114976
114977
114978
114979
114980
114981
114982
114983


114984
114985
114986
114987
114988
114989
114990
114991
114992
114993
114994
114995
114996
114997
114998
114999
115000
115001
115002
115003
115004
115005
115006
115007
115008
115009
115010
115011
115012
115013
115014
115015
115016
115017
115018
115019
115020
115021
115022
115023
  int mxBitCol;               /* Maximum column in pSrc->colUsed */
  CollSeq *pColl;             /* Collating sequence to on a column */
  WhereLoop *pLoop;           /* The Loop object */
  char *zNotUsed;             /* Extra space on the end of pIdx */
  Bitmask idxCols;            /* Bitmap of columns used for indexing */
  Bitmask extraCols;          /* Bitmap of additional columns */
  u8 sentWarning = 0;         /* True if a warnning has been issued */



  /* Generate code to skip over the creation and initialization of the
  ** transient index on 2nd and subsequent iterations of the loop. */
  v = pParse->pVdbe;
  assert( v!=0 );
  addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);

  /* Count the number of columns that will be added to the index
  ** and used to match WHERE clause constraints */
  nKeyCol = 0;
  pTable = pSrc->pTab;
  pWCEnd = &pWC->a[pWC->nTerm];
  pLoop = pLevel->pWLoop;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){






    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
      testcase( iCol==BMS );
      testcase( iCol==BMS-1 );
      if( !sentWarning ){
        sqlite3_log(SQLITE_WARNING_AUTOINDEX,
            "automatic index on %s(%s)", pTable->zName,
            pTable->aCol[iCol].zName);
        sentWarning = 1;
      }
      if( (idxCols & cMask)==0 ){
        if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ) return;


        pLoop->aLTerm[nKeyCol++] = pTerm;
        idxCols |= cMask;
      }
    }
  }
  assert( nKeyCol>0 );
  pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol;
  pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
                     | WHERE_AUTO_INDEX;

  /* Count the number of additional columns needed to create a
  ** covering index.  A "covering index" is an index that contains all
  ** columns that are needed by the query.  With a covering index, the
  ** original table never needs to be accessed.  Automatic indices must
  ** be a covering index because the index will not be updated if the
  ** original table changes and the index and table cannot both be used
  ** if they go out of sync.
  */
  extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
  mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
  testcase( pTable->nCol==BMS-1 );
  testcase( pTable->nCol==BMS-2 );
  for(i=0; i<mxBitCol; i++){
    if( extraCols & MASKBIT(i) ) nKeyCol++;
  }
  if( pSrc->colUsed & MASKBIT(BMS-1) ){
    nKeyCol += pTable->nCol - BMS + 1;
  }
  pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;

  /* Construct the Index object to describe this index */
  pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
  if( pIdx==0 ) return;
  pLoop->u.btree.pIndex = pIdx;
  pIdx->zName = "auto-index";
  pIdx->pTable = pTable;
  n = 0;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){







>
>















>
>
>
>
>
>












|
>
>



















|








<



|







116178
116179
116180
116181
116182
116183
116184
116185
116186
116187
116188
116189
116190
116191
116192
116193
116194
116195
116196
116197
116198
116199
116200
116201
116202
116203
116204
116205
116206
116207
116208
116209
116210
116211
116212
116213
116214
116215
116216
116217
116218
116219
116220
116221
116222
116223
116224
116225
116226
116227
116228
116229
116230
116231
116232
116233
116234
116235
116236
116237
116238
116239
116240
116241
116242
116243
116244
116245
116246
116247
116248
116249
116250

116251
116252
116253
116254
116255
116256
116257
116258
116259
116260
116261
  int mxBitCol;               /* Maximum column in pSrc->colUsed */
  CollSeq *pColl;             /* Collating sequence to on a column */
  WhereLoop *pLoop;           /* The Loop object */
  char *zNotUsed;             /* Extra space on the end of pIdx */
  Bitmask idxCols;            /* Bitmap of columns used for indexing */
  Bitmask extraCols;          /* Bitmap of additional columns */
  u8 sentWarning = 0;         /* True if a warnning has been issued */
  Expr *pPartial = 0;         /* Partial Index Expression */
  int iContinue = 0;          /* Jump here to skip excluded rows */

  /* Generate code to skip over the creation and initialization of the
  ** transient index on 2nd and subsequent iterations of the loop. */
  v = pParse->pVdbe;
  assert( v!=0 );
  addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);

  /* Count the number of columns that will be added to the index
  ** and used to match WHERE clause constraints */
  nKeyCol = 0;
  pTable = pSrc->pTab;
  pWCEnd = &pWC->a[pWC->nTerm];
  pLoop = pLevel->pWLoop;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( pLoop->prereq==0
     && (pTerm->wtFlags & TERM_VIRTUAL)==0
     && sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){
      pPartial = sqlite3ExprAnd(pParse->db, pPartial,
                                sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
    }
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
      testcase( iCol==BMS );
      testcase( iCol==BMS-1 );
      if( !sentWarning ){
        sqlite3_log(SQLITE_WARNING_AUTOINDEX,
            "automatic index on %s(%s)", pTable->zName,
            pTable->aCol[iCol].zName);
        sentWarning = 1;
      }
      if( (idxCols & cMask)==0 ){
        if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){
          goto end_auto_index_create;
        }
        pLoop->aLTerm[nKeyCol++] = pTerm;
        idxCols |= cMask;
      }
    }
  }
  assert( nKeyCol>0 );
  pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol;
  pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
                     | WHERE_AUTO_INDEX;

  /* Count the number of additional columns needed to create a
  ** covering index.  A "covering index" is an index that contains all
  ** columns that are needed by the query.  With a covering index, the
  ** original table never needs to be accessed.  Automatic indices must
  ** be a covering index because the index will not be updated if the
  ** original table changes and the index and table cannot both be used
  ** if they go out of sync.
  */
  extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
  mxBitCol = MIN(BMS-1,pTable->nCol);
  testcase( pTable->nCol==BMS-1 );
  testcase( pTable->nCol==BMS-2 );
  for(i=0; i<mxBitCol; i++){
    if( extraCols & MASKBIT(i) ) nKeyCol++;
  }
  if( pSrc->colUsed & MASKBIT(BMS-1) ){
    nKeyCol += pTable->nCol - BMS + 1;
  }


  /* Construct the Index object to describe this index */
  pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
  if( pIdx==0 ) goto end_auto_index_create;
  pLoop->u.btree.pIndex = pIdx;
  pIdx->zName = "auto-index";
  pIdx->pTable = pTable;
  n = 0;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
115061
115062
115063
115064
115065
115066
115067

115068





115069
115070
115071
115072

115073
115074
115075
115076

115077
115078
115079



115080
115081
115082
115083
115084
115085
115086
  assert( pLevel->iIdxCur>=0 );
  pLevel->iIdxCur = pParse->nTab++;
  sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
  sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  VdbeComment((v, "for %s", pTable->zName));

  /* Fill the automatic index with content */

  addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);





  regRecord = sqlite3GetTempReg(pParse);
  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);

  sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);

  
  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);



}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Allocate and populate an sqlite3_index_info structure. It is the 
** responsibility of the caller to eventually release the structure







>

>
>
>
>
>




>




>



>
>
>







116299
116300
116301
116302
116303
116304
116305
116306
116307
116308
116309
116310
116311
116312
116313
116314
116315
116316
116317
116318
116319
116320
116321
116322
116323
116324
116325
116326
116327
116328
116329
116330
116331
116332
116333
116334
116335
  assert( pLevel->iIdxCur>=0 );
  pLevel->iIdxCur = pParse->nTab++;
  sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
  sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  VdbeComment((v, "for %s", pTable->zName));

  /* Fill the automatic index with content */
  sqlite3ExprCachePush(pParse);
  addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
  if( pPartial ){
    iContinue = sqlite3VdbeMakeLabel(v);
    sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
    pLoop->wsFlags |= WHERE_PARTIALIDX;
  }
  regRecord = sqlite3GetTempReg(pParse);
  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
  sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3ExprCachePop(pParse);
  
  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);

end_auto_index_create:
  sqlite3ExprDelete(pParse->db, pPartial);
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Allocate and populate an sqlite3_index_info structure. It is the 
** responsibility of the caller to eventually release the structure
115232
115233
115234
115235
115236
115237
115238
115239
115240
115241
115242
115243
115244
115245
115246
115247
115248

115249
115250
115251
115252
115253
115254
115255
115256
115257
    }
  }

  return pParse->nErr;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */


#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
**
**    aStat[0]      Est. number of rows less than pVal
**    aStat[1]      Est. number of rows equal to pVal
**
** Return SQLITE_OK on success.

*/
static void whereKeyStats(
  Parse *pParse,              /* Database connection */
  Index *pIdx,                /* Index to consider domain of */
  UnpackedRecord *pRec,       /* Vector of values to consider */
  int roundUp,                /* Round up if true.  Round down if false */
  tRowcnt *aStat              /* OUT: stats written here */
){
  IndexSample *aSample = pIdx->aSample;







<








|
>

|







116481
116482
116483
116484
116485
116486
116487

116488
116489
116490
116491
116492
116493
116494
116495
116496
116497
116498
116499
116500
116501
116502
116503
116504
116505
116506
    }
  }

  return pParse->nErr;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */


#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
**
**    aStat[0]      Est. number of rows less than pVal
**    aStat[1]      Est. number of rows equal to pVal
**
** Return the index of the sample that is the smallest sample that
** is greater than or equal to pRec.
*/
static int whereKeyStats(
  Parse *pParse,              /* Database connection */
  Index *pIdx,                /* Index to consider domain of */
  UnpackedRecord *pRec,       /* Vector of values to consider */
  int roundUp,                /* Round up if true.  Round down if false */
  tRowcnt *aStat              /* OUT: stats written here */
){
  IndexSample *aSample = pIdx->aSample;
115325
115326
115327
115328
115329
115330
115331

115332
115333
115334
115335
115336
115337
115338
    if( roundUp ){
      iGap = (iGap*2)/3;
    }else{
      iGap = iGap/3;
    }
    aStat[0] = iLower + iGap;
  }

}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** If it is not NULL, pTerm is a term that provides an upper or lower
** bound on a range scan. Without considering pTerm, it is estimated 
** that the scan will visit nNew rows. This function returns the number







>







116574
116575
116576
116577
116578
116579
116580
116581
116582
116583
116584
116585
116586
116587
116588
    if( roundUp ){
      iGap = (iGap*2)/3;
    }else{
      iGap = iGap/3;
    }
    aStat[0] = iLower + iGap;
  }
  return i;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** If it is not NULL, pTerm is a term that provides an upper or lower
** bound on a range scan. Without considering pTerm, it is estimated 
** that the scan will visit nNew rows. This function returns the number
115475
115476
115477
115478
115479
115480
115481
115482
115483
115484
115485
115486
115487
115488
115489
115490
115491
115492
115493
115494
115495
115496
115497
115498
115499
115500
115501
115502
115503
115504
115505
**                    |_____|   |_____|
**                       |         |
**                     pLower    pUpper
**
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index
** column subject to the range constraint. Or, equivalently, the number of
** equality constraints optimized by the proposed index scan. For example,
** assuming index p is on t1(a, b), and the SQL query is:
**
**   ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
**
** then nEq is set to 1 (as the range restricted column, b, is the second 
** left-most column of the index). Or, if the query is:
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**
** then nEq is set to 0.
**
** When this function is called, *pnOut is set to the sqlite3LogEst() of the
** number of rows that the index scan is expected to visit without 
** considering the range constraints. If nEq is 0, this is the number of 
** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
** to account for the range constraints pLower and pUpper.
** 
** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
** used, a single range inequality reduces the search space by a factor of 4. 
** and a pair of constraints (x>? AND x<?) reduces the expected number of
** rows visited by a factor of 64.







|















|







116725
116726
116727
116728
116729
116730
116731
116732
116733
116734
116735
116736
116737
116738
116739
116740
116741
116742
116743
116744
116745
116746
116747
116748
116749
116750
116751
116752
116753
116754
116755
**                    |_____|   |_____|
**                       |         |
**                     pLower    pUpper
**
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index
** column subject to the range constraint. Or, equivalently, the number of
** equality constraints optimized by the proposed index scan. For example,
** assuming index p is on t1(a, b), and the SQL query is:
**
**   ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
**
** then nEq is set to 1 (as the range restricted column, b, is the second 
** left-most column of the index). Or, if the query is:
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**
** then nEq is set to 0.
**
** When this function is called, *pnOut is set to the sqlite3LogEst() of the
** number of rows that the index scan is expected to visit without 
** considering the range constraints. If nEq is 0, then *pnOut is the number of 
** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
** to account for the range constraints pLower and pUpper.
** 
** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
** used, a single range inequality reduces the search space by a factor of 4. 
** and a pair of constraints (x>? AND x<?) reduces the expected number of
** rows visited by a factor of 64.
115515
115516
115517
115518
115519
115520
115521
115522
115523
115524
115525
115526
115527
115528
115529
115530
115531
115532
115533
115534
115535
115536
115537
115538
115539
115540
115541
115542
115543
115544
115545
115546


115547
115548
115549


115550
115551
115552
115553
115554
115555
115556
115557
115558
115559
115560
115561
115562
115563
115564
115565
115566
115567
115568
115569
115570








115571
115572
115573
115574
115575
115576
115577
115578
115579
115580
115581
115582
115583
115584
115585
115586
115587
115588
115589
115590
115591
115592
115593
115594
115595
115596
115597
115598
115599
115600
115601
115602
115603
115604
115605
115606
115607





115608
115609
115610
115611
115612
115613
115614
  int nOut = pLoop->nOut;
  LogEst nNew;

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  Index *p = pLoop->u.btree.pIndex;
  int nEq = pLoop->u.btree.nEq;

  if( p->nSample>0
   && nEq<p->nSampleCol
   && OptimizationEnabled(pParse->db, SQLITE_Stat3) 
  ){
    if( nEq==pBuilder->nRecValid ){
      UnpackedRecord *pRec = pBuilder->pRec;
      tRowcnt a[2];
      u8 aff;

      /* Variable iLower will be set to the estimate of the number of rows in 
      ** the index that are less than the lower bound of the range query. The
      ** lower bound being the concatenation of $P and $L, where $P is the
      ** key-prefix formed by the nEq values matched against the nEq left-most
      ** columns of the index, and $L is the value in pLower.
      **
      ** Or, if pLower is NULL or $L cannot be extracted from it (because it
      ** is not a simple variable or literal value), the lower bound of the
      ** range is $P. Due to a quirk in the way whereKeyStats() works, even
      ** if $L is available, whereKeyStats() is called for both ($P) and 
      ** ($P:$L) and the larger of the two returned values used.
      **
      ** Similarly, iUpper is to be set to the estimate of the number of rows
      ** less than the upper bound of the range query. Where the upper bound
      ** is either ($P) or ($P:$U). Again, even if $U is available, both values
      ** of iUpper are requested of whereKeyStats() and the smaller used.


      */
      tRowcnt iLower;
      tRowcnt iUpper;



      if( pRec ){
        testcase( pRec->nField!=pBuilder->nRecValid );
        pRec->nField = pBuilder->nRecValid;
      }
      if( nEq==p->nKeyCol ){
        aff = SQLITE_AFF_INTEGER;
      }else{
        aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
      }
      /* Determine iLower and iUpper using ($P) only. */
      if( nEq==0 ){
        iLower = 0;
        iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
      }else{
        /* Note: this call could be optimized away - since the same values must 
        ** have been requested when testing key $P in whereEqualScanEst().  */
        whereKeyStats(pParse, p, pRec, 0, a);
        iLower = a[0];
        iUpper = a[0] + a[1];
      }









      /* If possible, improve on the iLower estimate using ($P:$L). */
      if( pLower ){
        int bOk;                    /* True if value is extracted from pExpr */
        Expr *pExpr = pLower->pExpr->pRight;
        assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
        if( rc==SQLITE_OK && bOk ){
          tRowcnt iNew;
          whereKeyStats(pParse, p, pRec, 0, a);
          iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
          if( iNew>iLower ) iLower = iNew;
          nOut--;
          pLower = 0;
        }
      }

      /* If possible, improve on the iUpper estimate using ($P:$U). */
      if( pUpper ){
        int bOk;                    /* True if value is extracted from pExpr */
        Expr *pExpr = pUpper->pExpr->pRight;
        assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
        if( rc==SQLITE_OK && bOk ){
          tRowcnt iNew;
          whereKeyStats(pParse, p, pRec, 1, a);
          iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
          if( iNew<iUpper ) iUpper = iNew;
          nOut--;
          pUpper = 0;
        }
      }

      pBuilder->pRec = pRec;
      if( rc==SQLITE_OK ){
        if( iUpper>iLower ){
          nNew = sqlite3LogEst(iUpper - iLower);





        }else{
          nNew = 10;        assert( 10==sqlite3LogEst(2) );
        }
        if( nNew<nOut ){
          nOut = nNew;
        }
        WHERETRACE(0x10, ("STAT4 range scan: %u..%u  est=%d\n",







|
<
<
<















|





>
>

|
|
>
>













|







>
>
>
>
>
>
>
>





<



|
|










<



|
|










>
>
>
>
>







116765
116766
116767
116768
116769
116770
116771
116772



116773
116774
116775
116776
116777
116778
116779
116780
116781
116782
116783
116784
116785
116786
116787
116788
116789
116790
116791
116792
116793
116794
116795
116796
116797
116798
116799
116800
116801
116802
116803
116804
116805
116806
116807
116808
116809
116810
116811
116812
116813
116814
116815
116816
116817
116818
116819
116820
116821
116822
116823
116824
116825
116826
116827
116828
116829
116830
116831
116832
116833
116834

116835
116836
116837
116838
116839
116840
116841
116842
116843
116844
116845
116846
116847
116848
116849

116850
116851
116852
116853
116854
116855
116856
116857
116858
116859
116860
116861
116862
116863
116864
116865
116866
116867
116868
116869
116870
116871
116872
116873
116874
116875
116876
  int nOut = pLoop->nOut;
  LogEst nNew;

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  Index *p = pLoop->u.btree.pIndex;
  int nEq = pLoop->u.btree.nEq;

  if( p->nSample>0 && nEq<p->nSampleCol ){



    if( nEq==pBuilder->nRecValid ){
      UnpackedRecord *pRec = pBuilder->pRec;
      tRowcnt a[2];
      u8 aff;

      /* Variable iLower will be set to the estimate of the number of rows in 
      ** the index that are less than the lower bound of the range query. The
      ** lower bound being the concatenation of $P and $L, where $P is the
      ** key-prefix formed by the nEq values matched against the nEq left-most
      ** columns of the index, and $L is the value in pLower.
      **
      ** Or, if pLower is NULL or $L cannot be extracted from it (because it
      ** is not a simple variable or literal value), the lower bound of the
      ** range is $P. Due to a quirk in the way whereKeyStats() works, even
      ** if $L is available, whereKeyStats() is called for both ($P) and 
      ** ($P:$L) and the larger of the two returned values is used.
      **
      ** Similarly, iUpper is to be set to the estimate of the number of rows
      ** less than the upper bound of the range query. Where the upper bound
      ** is either ($P) or ($P:$U). Again, even if $U is available, both values
      ** of iUpper are requested of whereKeyStats() and the smaller used.
      **
      ** The number of rows between the two bounds is then just iUpper-iLower.
      */
      tRowcnt iLower;     /* Rows less than the lower bound */
      tRowcnt iUpper;     /* Rows less than the upper bound */
      int iLwrIdx = -2;   /* aSample[] for the lower bound */
      int iUprIdx = -1;   /* aSample[] for the upper bound */

      if( pRec ){
        testcase( pRec->nField!=pBuilder->nRecValid );
        pRec->nField = pBuilder->nRecValid;
      }
      if( nEq==p->nKeyCol ){
        aff = SQLITE_AFF_INTEGER;
      }else{
        aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
      }
      /* Determine iLower and iUpper using ($P) only. */
      if( nEq==0 ){
        iLower = 0;
        iUpper = p->nRowEst0;
      }else{
        /* Note: this call could be optimized away - since the same values must 
        ** have been requested when testing key $P in whereEqualScanEst().  */
        whereKeyStats(pParse, p, pRec, 0, a);
        iLower = a[0];
        iUpper = a[0] + a[1];
      }

      assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
      assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
      assert( p->aSortOrder!=0 );
      if( p->aSortOrder[nEq] ){
        /* The roles of pLower and pUpper are swapped for a DESC index */
        SWAP(WhereTerm*, pLower, pUpper);
      }

      /* If possible, improve on the iLower estimate using ($P:$L). */
      if( pLower ){
        int bOk;                    /* True if value is extracted from pExpr */
        Expr *pExpr = pLower->pExpr->pRight;

        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
        if( rc==SQLITE_OK && bOk ){
          tRowcnt iNew;
          iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a);
          iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
          if( iNew>iLower ) iLower = iNew;
          nOut--;
          pLower = 0;
        }
      }

      /* If possible, improve on the iUpper estimate using ($P:$U). */
      if( pUpper ){
        int bOk;                    /* True if value is extracted from pExpr */
        Expr *pExpr = pUpper->pExpr->pRight;

        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
        if( rc==SQLITE_OK && bOk ){
          tRowcnt iNew;
          iUprIdx = whereKeyStats(pParse, p, pRec, 1, a);
          iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
          if( iNew<iUpper ) iUpper = iNew;
          nOut--;
          pUpper = 0;
        }
      }

      pBuilder->pRec = pRec;
      if( rc==SQLITE_OK ){
        if( iUpper>iLower ){
          nNew = sqlite3LogEst(iUpper - iLower);
          /* TUNING:  If both iUpper and iLower are derived from the same
          ** sample, then assume they are 4x more selective.  This brings
          ** the estimated selectivity more in line with what it would be
          ** if estimated without the use of STAT3/4 tables. */
          if( iLwrIdx==iUprIdx ) nNew -= 20;  assert( 20==sqlite3LogEst(4) );
        }else{
          nNew = 10;        assert( 10==sqlite3LogEst(2) );
        }
        if( nNew<nOut ){
          nOut = nNew;
        }
        WHERETRACE(0x10, ("STAT4 range scan: %u..%u  est=%d\n",
115625
115626
115627
115628
115629
115630
115631
115632

115633
115634
115635
115636

115637

115638
115639
115640
115641
115642
115643
115644
  UNUSED_PARAMETER(pBuilder);
  assert( pLower || pUpper );
#endif
  assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 );
  nNew = whereRangeAdjust(pLower, nOut);
  nNew = whereRangeAdjust(pUpper, nNew);

  /* TUNING: If there is both an upper and lower limit, assume the range is

  ** reduced by an additional 75%. This means that, by default, an open-ended
  ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the
  ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to
  ** match 1/64 of the index. */ 

  if( pLower && pUpper ) nNew -= 20;


  nOut -= (pLower!=0) + (pUpper!=0);
  if( nNew<10 ) nNew = 10;
  if( nNew<nOut ) nOut = nNew;
#if defined(WHERETRACE_ENABLED)
  if( pLoop->nOut>nOut ){
    WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n",







|
>




>
|
>







116887
116888
116889
116890
116891
116892
116893
116894
116895
116896
116897
116898
116899
116900
116901
116902
116903
116904
116905
116906
116907
116908
116909
  UNUSED_PARAMETER(pBuilder);
  assert( pLower || pUpper );
#endif
  assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 );
  nNew = whereRangeAdjust(pLower, nOut);
  nNew = whereRangeAdjust(pUpper, nNew);

  /* TUNING: If there is both an upper and lower limit and neither limit
  ** has an application-defined likelihood(), assume the range is
  ** reduced by an additional 75%. This means that, by default, an open-ended
  ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the
  ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to
  ** match 1/64 of the index. */ 
  if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){
    nNew -= 20;
  }

  nOut -= (pLower!=0) + (pUpper!=0);
  if( nNew<10 ) nNew = 10;
  if( nNew<nOut ) nOut = nNew;
#if defined(WHERETRACE_ENABLED)
  if( pLoop->nOut>nOut ){
    WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n",
115990
115991
115992
115993
115994
115995
115996
115997
115998
115999
116000
116001
116002
116003
116004
  int nReg;                     /* Number of registers to allocate */
  char *zAff;                   /* Affinity string to return */

  /* This module is only called on query plans that use an index. */
  pLoop = pLevel->pWLoop;
  assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
  nEq = pLoop->u.btree.nEq;
  nSkip = pLoop->u.btree.nSkip;
  pIdx = pLoop->u.btree.pIndex;
  assert( pIdx!=0 );

  /* Figure out how many memory cells we will need then allocate them.
  */
  regBase = pParse->nMem + 1;
  nReg = pLoop->u.btree.nEq + nExtraReg;







|







117255
117256
117257
117258
117259
117260
117261
117262
117263
117264
117265
117266
117267
117268
117269
  int nReg;                     /* Number of registers to allocate */
  char *zAff;                   /* Affinity string to return */

  /* This module is only called on query plans that use an index. */
  pLoop = pLevel->pWLoop;
  assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
  nEq = pLoop->u.btree.nEq;
  nSkip = pLoop->nSkip;
  pIdx = pLoop->u.btree.pIndex;
  assert( pIdx!=0 );

  /* Figure out how many memory cells we will need then allocate them.
  */
  regBase = pParse->nMem + 1;
  nReg = pLoop->u.btree.nEq + nExtraReg;
116089
116090
116091
116092
116093
116094
116095
116096
116097
116098
116099
116100
116101
116102
116103
116104
116105
116106
116107
116108
116109
116110
116111
116112
116113
116114
116115
116116
116117
116118
116119
116120
116121
116122
116123
116124
116125
116126
116127
116128
116129
116130
116131
116132
116133
116134
116135
116136
116137
116138
116139
116140
116141
116142
116143
116144
116145
116146
116147
116148
116149
116150
116151
116152
116153
116154
116155

116156
116157


116158
116159
116160
116161
116162
116163
116164
116165
116166

116167
116168
116169
116170
116171
116172
116173
116174
116175
116176
116177
116178



116179
116180
116181
116182
116183
116184
116185
116186
116187


116188
116189
116190
116191
116192
116193
116194
116195
116196
116197
116198
116199
116200
116201
116202
116203


116204
116205

116206



116207
116208
116209
116210
116211
116212
116213
116214
116215



116216
116217
116218
116219
116220
116221
116222
116223
116224

116225
116226
116227


116228
116229
116230
116231
116232
116233
116234







116235
116236
116237

116238
116239
116240
116241
































116242
116243
116244
116245
116246
116247
116248
  sqlite3StrAccumAppendAll(pStr, zColumn);
  sqlite3StrAccumAppend(pStr, zOp, 1);
  sqlite3StrAccumAppend(pStr, "?", 1);
}

/*
** Argument pLevel describes a strategy for scanning table pTab. This 
** function returns a pointer to a string buffer containing a description
** of the subset of table rows scanned by the strategy in the form of an
** SQL expression. Or, if all rows are scanned, NULL is returned.
**
** For example, if the query:
**
**   SELECT * FROM t1 WHERE a=1 AND b>2;
**
** is run and there is an index on (a, b), then this function returns a
** string similar to:
**
**   "a=? AND b>?"
**
** The returned pointer points to memory obtained from sqlite3DbMalloc().
** It is the responsibility of the caller to free the buffer when it is
** no longer required.
*/
static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
  Index *pIndex = pLoop->u.btree.pIndex;
  u16 nEq = pLoop->u.btree.nEq;
  u16 nSkip = pLoop->u.btree.nSkip;
  int i, j;
  Column *aCol = pTab->aCol;
  i16 *aiColumn = pIndex->aiColumn;
  StrAccum txt;

  if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
    return 0;
  }
  sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
  txt.db = db;
  sqlite3StrAccumAppend(&txt, " (", 2);
  for(i=0; i<nEq; i++){
    char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
    if( i>=nSkip ){
      explainAppendTerm(&txt, i, z, "=");
    }else{
      if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
      sqlite3StrAccumAppend(&txt, "ANY(", 4);
      sqlite3StrAccumAppendAll(&txt, z);
      sqlite3StrAccumAppend(&txt, ")", 1);
    }
  }

  j = i;
  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
    char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(&txt, i++, z, ">");
  }
  if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
    char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(&txt, i, z, "<");
  }
  sqlite3StrAccumAppend(&txt, ")", 1);
  return sqlite3StrAccumFinish(&txt);
}

/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single

** record is added to the output to describe the table scan strategy in 
** pLevel.


*/
static void explainOneScan(
  Parse *pParse,                  /* Parse context */
  SrcList *pTabList,              /* Table list this loop refers to */
  WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
  int iLevel,                     /* Value for "level" column of output */
  int iFrom,                      /* Value for "from" column of output */
  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
){

#ifndef SQLITE_DEBUG
  if( pParse->explain==2 )
#endif
  {
    struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
    sqlite3 *db = pParse->db;     /* Database handle */
    char *zMsg;                   /* Text to add to EQP output */
    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
    int isSearch;                 /* True for a SEARCH. False for SCAN. */
    WhereLoop *pLoop;             /* The controlling WhereLoop object */
    u32 flags;                    /* Flags that describe this loop */




    pLoop = pLevel->pWLoop;
    flags = pLoop->wsFlags;
    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;

    isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
            || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
            || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));



    zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
    if( pItem->pSelect ){
      zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
    }else{
      zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
    }

    if( pItem->zAlias ){
      zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
    }
    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
     && ALWAYS(pLoop->u.btree.pIndex!=0)
    ){
      const char *zFmt;
      Index *pIdx = pLoop->u.btree.pIndex;
      char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);


      assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
      if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){

        zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s";



      }else if( flags & WHERE_AUTO_INDEX ){
        zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s";
      }else if( flags & WHERE_IDX_ONLY ){
        zFmt = "%s USING COVERING INDEX %s%s";
      }else{
        zFmt = "%s USING INDEX %s%s";
      }
      zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere);
      sqlite3DbFree(db, zWhere);



    }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
      zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);

      if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
      }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
      }else if( flags&WHERE_BTM_LIMIT ){
        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);

      }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
      }


    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
      zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
                  pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
    }
#endif







    zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
    sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  }

}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE_OMIT_EXPLAIN */


































/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
static Bitmask codeOneLoopStart(







|
|
<









<
<
<
<

|


|



<

|
<
<
<
<
|



|

|
<
|
<






|



|

|
<




|
>
|
|
>
>

|







>
|






<




>
>
>



|





>
>
|

|

|



|

|
<
<
|
|
|
>
>


>
|
>
>
>

|

|

|

|
|
>
>
>

<
|

|

|

|
>
|
|

>
>



|



>
>
>
>
>
>
>
|
|

>


|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







117354
117355
117356
117357
117358
117359
117360
117361
117362

117363
117364
117365
117366
117367
117368
117369
117370
117371




117372
117373
117374
117375
117376
117377
117378
117379

117380
117381




117382
117383
117384
117385
117386
117387
117388

117389

117390
117391
117392
117393
117394
117395
117396
117397
117398
117399
117400
117401
117402

117403
117404
117405
117406
117407
117408
117409
117410
117411
117412
117413
117414
117415
117416
117417
117418
117419
117420
117421
117422
117423
117424
117425
117426
117427
117428
117429

117430
117431
117432
117433
117434
117435
117436
117437
117438
117439
117440
117441
117442
117443
117444
117445
117446
117447
117448
117449
117450
117451
117452
117453
117454
117455
117456
117457
117458


117459
117460
117461
117462
117463
117464
117465
117466
117467
117468
117469
117470
117471
117472
117473
117474
117475
117476
117477
117478
117479
117480
117481
117482
117483

117484
117485
117486
117487
117488
117489
117490
117491
117492
117493
117494
117495
117496
117497
117498
117499
117500
117501
117502
117503
117504
117505
117506
117507
117508
117509
117510
117511
117512
117513
117514
117515
117516
117517
117518
117519
117520
117521
117522
117523
117524
117525
117526
117527
117528
117529
117530
117531
117532
117533
117534
117535
117536
117537
117538
117539
117540
117541
117542
117543
117544
117545
117546
117547
117548
117549
117550
117551
117552
117553
117554
117555
117556
117557
  sqlite3StrAccumAppendAll(pStr, zColumn);
  sqlite3StrAccumAppend(pStr, zOp, 1);
  sqlite3StrAccumAppend(pStr, "?", 1);
}

/*
** Argument pLevel describes a strategy for scanning table pTab. This 
** function appends text to pStr that describes the subset of table
** rows scanned by the strategy in the form of an SQL expression.

**
** For example, if the query:
**
**   SELECT * FROM t1 WHERE a=1 AND b>2;
**
** is run and there is an index on (a, b), then this function returns a
** string similar to:
**
**   "a=? AND b>?"




*/
static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
  Index *pIndex = pLoop->u.btree.pIndex;
  u16 nEq = pLoop->u.btree.nEq;
  u16 nSkip = pLoop->nSkip;
  int i, j;
  Column *aCol = pTab->aCol;
  i16 *aiColumn = pIndex->aiColumn;


  if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;




  sqlite3StrAccumAppend(pStr, " (", 2);
  for(i=0; i<nEq; i++){
    char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
    if( i>=nSkip ){
      explainAppendTerm(pStr, i, z, "=");
    }else{
      if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);

      sqlite3XPrintf(pStr, 0, "ANY(%s)", z);

    }
  }

  j = i;
  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
    char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(pStr, i++, z, ">");
  }
  if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
    char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(pStr, i, z, "<");
  }
  sqlite3StrAccumAppend(pStr, ")", 1);

}

/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
** defined at compile-time. If it is not a no-op, a single OP_Explain opcode 
** is added to the output to describe the table scan strategy in pLevel.
**
** If an OP_Explain opcode is added to the VM, its address is returned.
** Otherwise, if no OP_Explain is coded, zero is returned.
*/
static int explainOneScan(
  Parse *pParse,                  /* Parse context */
  SrcList *pTabList,              /* Table list this loop refers to */
  WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
  int iLevel,                     /* Value for "level" column of output */
  int iFrom,                      /* Value for "from" column of output */
  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
){
  int ret = 0;
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
  if( pParse->explain==2 )
#endif
  {
    struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
    sqlite3 *db = pParse->db;     /* Database handle */

    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
    int isSearch;                 /* True for a SEARCH. False for SCAN. */
    WhereLoop *pLoop;             /* The controlling WhereLoop object */
    u32 flags;                    /* Flags that describe this loop */
    char *zMsg;                   /* Text to add to EQP output */
    StrAccum str;                 /* EQP output string */
    char zBuf[100];               /* Initial space for EQP output string */

    pLoop = pLevel->pWLoop;
    flags = pLoop->wsFlags;
    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0;

    isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
            || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
            || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));

    sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
    str.db = db;
    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
    if( pItem->pSelect ){
      sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
    }else{
      sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
    }

    if( pItem->zAlias ){
      sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
    }
    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){


      const char *zFmt = 0;
      Index *pIdx;

      assert( pLoop->u.btree.pIndex!=0 );
      pIdx = pLoop->u.btree.pIndex;
      assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
      if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
        if( isSearch ){
          zFmt = "PRIMARY KEY";
        }
      }else if( flags & WHERE_PARTIALIDX ){
        zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
      }else if( flags & WHERE_AUTO_INDEX ){
        zFmt = "AUTOMATIC COVERING INDEX";
      }else if( flags & WHERE_IDX_ONLY ){
        zFmt = "COVERING INDEX %s";
      }else{
        zFmt = "INDEX %s";
      }
      if( zFmt ){
        sqlite3StrAccumAppend(&str, " USING ", 7);
        sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
        explainIndexRange(&str, pLoop, pItem->pTab);
      }
    }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){

      const char *zRange;
      if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
        zRange = "(rowid=?)";
      }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
        zRange = "(rowid>? AND rowid<?)";
      }else if( flags&WHERE_BTM_LIMIT ){
        zRange = "(rowid>?)";
      }else{
        assert( flags&WHERE_TOP_LIMIT);
        zRange = "(rowid<?)";
      }
      sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
      sqlite3StrAccumAppendAll(&str, zRange);
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
      sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
                  pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
    }
#endif
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
    if( pLoop->nOut>=10 ){
      sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
    }else{
      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
    }
#endif
    zMsg = sqlite3StrAccumFinish(&str);
    ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
  }
  return ret;
}
#else
# define explainOneScan(u,v,w,x,y,z) 0
#endif /* SQLITE_OMIT_EXPLAIN */

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Configure the VM passed as the first argument with an
** sqlite3_stmt_scanstatus() entry corresponding to the scan used to 
** implement level pLvl. Argument pSrclist is a pointer to the FROM 
** clause that the scan reads data from.
**
** If argument addrExplain is not 0, it must be the address of an 
** OP_Explain instruction that describes the same loop.
*/
static void addScanStatus(
  Vdbe *v,                        /* Vdbe to add scanstatus entry to */
  SrcList *pSrclist,              /* FROM clause pLvl reads data from */
  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
  int addrExplain                 /* Address of OP_Explain (or 0) */
){
  const char *zObj = 0;
  WhereLoop *pLoop = pLvl->pWLoop;
  if( (pLoop->wsFlags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
    zObj = pLoop->u.btree.pIndex->zName;
  }else{
    zObj = pSrclist->a[pLvl->iFrom].zName;
  }
  sqlite3VdbeScanStatus(
      v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
  );
}
#else
# define addScanStatus(a, b, c, d) ((void)d)
#endif



/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
static Bitmask codeOneLoopStart(
116536
116537
116538
116539
116540
116541
116542
116543
116544
116545
116546
116547
116548
116549
116550
116551
116552
116553
116554
116555
116556
116557
116558
116559
116560
116561
116562
116563
116564
116565
116566
116567
    char *zStartAff;             /* Affinity for start of range constraint */
    char cEndAff = 0;            /* Affinity for end of range constraint */
    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */

    pIdx = pLoop->u.btree.pIndex;
    iIdxCur = pLevel->iIdxCur;
    assert( nEq>=pLoop->u.btree.nSkip );

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
    ** query, then the caller will only allow the loop to run for
    ** a single iteration. This means that the first row returned
    ** should not have a NULL value stored in 'x'. If column 'x' is
    ** the first one after the nEq equality constraints in the index,
    ** this requires some special handling.
    */
    assert( pWInfo->pOrderBy==0
         || pWInfo->pOrderBy->nExpr==1
         || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
    if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
     && pWInfo->nOBSat>0
     && (pIdx->nKeyCol>nEq)
    ){
      assert( pLoop->u.btree.nSkip==0 );
      bSeekPastNull = 1;
      nExtraReg = 1;
    }

    /* Find any inequality constraint terms for the start and end 
    ** of the range. 
    */







|
















|







117845
117846
117847
117848
117849
117850
117851
117852
117853
117854
117855
117856
117857
117858
117859
117860
117861
117862
117863
117864
117865
117866
117867
117868
117869
117870
117871
117872
117873
117874
117875
117876
    char *zStartAff;             /* Affinity for start of range constraint */
    char cEndAff = 0;            /* Affinity for end of range constraint */
    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */

    pIdx = pLoop->u.btree.pIndex;
    iIdxCur = pLevel->iIdxCur;
    assert( nEq>=pLoop->nSkip );

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
    ** query, then the caller will only allow the loop to run for
    ** a single iteration. This means that the first row returned
    ** should not have a NULL value stored in 'x'. If column 'x' is
    ** the first one after the nEq equality constraints in the index,
    ** this requires some special handling.
    */
    assert( pWInfo->pOrderBy==0
         || pWInfo->pOrderBy->nExpr==1
         || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
    if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
     && pWInfo->nOBSat>0
     && (pIdx->nKeyCol>nEq)
    ){
      assert( pLoop->nSkip==0 );
      bSeekPastNull = 1;
      nExtraReg = 1;
    }

    /* Find any inequality constraint terms for the start and end 
    ** of the range. 
    */
116882
116883
116884
116885
116886
116887
116888
116889

116890
116891
116892
116893
116894
116895
116896
116897
116898
116899
116900
116901

116902
116903
116904
116905
116906
116907
116908
116909


116910
116911
116912
116913
116914
116915
116916
      }
    }

    /* Run a separate WHERE clause for each term of the OR clause.  After
    ** eliminating duplicates from other WHERE clauses, the action for each
    ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
    */
    wctrlFlags =  WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |

                  WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY;
    for(ii=0; ii<pOrWc->nTerm; ii++){
      WhereTerm *pOrTerm = &pOrWc->a[ii];
      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
        WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
        Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
        int j1 = 0;                     /* Address of jump operation */
        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */

        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                                      wctrlFlags, iCovCur);
        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          explainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
          );


          /* This is the sub-WHERE clause body.  First skip over
          ** duplicate rows from prior sub-WHERE clauses, and record the
          ** rowid (or PRIMARY KEY) for the current row so that the same
          ** row will be skipped in subsequent sub-WHERE clauses.
          */
          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
            int r;







|
>
|











>





|


>
>







118191
118192
118193
118194
118195
118196
118197
118198
118199
118200
118201
118202
118203
118204
118205
118206
118207
118208
118209
118210
118211
118212
118213
118214
118215
118216
118217
118218
118219
118220
118221
118222
118223
118224
118225
118226
118227
118228
118229
      }
    }

    /* Run a separate WHERE clause for each term of the OR clause.  After
    ** eliminating duplicates from other WHERE clauses, the action for each
    ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
    */
    wctrlFlags =  WHERE_OMIT_OPEN_CLOSE
                | WHERE_FORCE_TABLE
                | WHERE_ONETABLE_ONLY;
    for(ii=0; ii<pOrWc->nTerm; ii++){
      WhereTerm *pOrTerm = &pOrWc->a[ii];
      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
        WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
        Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
        int j1 = 0;                     /* Address of jump operation */
        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */
        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                                      wctrlFlags, iCovCur);
        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          int addrExplain = explainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
          );
          addScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);

          /* This is the sub-WHERE clause body.  First skip over
          ** duplicate rows from prior sub-WHERE clauses, and record the
          ** rowid (or PRIMARY KEY) for the current row so that the same
          ** row will be skipped in subsequent sub-WHERE clauses.
          */
          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
            int r;
117032
117033
117034
117035
117036
117037
117038




117039
117040
117041
117042
117043
117044
117045
      pLevel->p1 = iCur;
      pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
      VdbeCoverageIf(v, bRev==0);
      VdbeCoverageIf(v, bRev!=0);
      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
    }
  }





  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    testcase( pTerm->wtFlags & TERM_VIRTUAL );







>
>
>
>







118345
118346
118347
118348
118349
118350
118351
118352
118353
118354
118355
118356
118357
118358
118359
118360
118361
118362
      pLevel->p1 = iCur;
      pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
      VdbeCoverageIf(v, bRev==0);
      VdbeCoverageIf(v, bRev!=0);
      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
    }
  }

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
#endif

  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    testcase( pTerm->wtFlags & TERM_VIRTUAL );
117114
117115
117116
117117
117118
117119
117120
117121
117122
117123
117124
117125



117126
117127
117128
117129
117130

117131

117132
117133
117134
117135

117136
117137
117138
117139
117140
117141
117142
      pTerm->wtFlags |= TERM_CODED;
    }
  }

  return pLevel->notReady;
}

#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Generate "Explanation" text for a WhereTerm.
*/
static void whereExplainTerm(Vdbe *v, WhereTerm *pTerm){



  char zType[4];
  memcpy(zType, "...", 4);
  if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
  if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
  if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';

  sqlite3ExplainPrintf(v, "%s ", zType);

  sqlite3ExplainExpr(v, pTerm->pExpr);
}
#endif /* WHERETRACE_ENABLED && SQLITE_ENABLE_TREE_EXPLAIN */



#ifdef WHERETRACE_ENABLED
/*
** Print a WhereLoop object for debugging purposes
*/
static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
  WhereInfo *pWInfo = pWC->pWInfo;







|

|

|
>
>
>
|
|
|
|
|
>
|
>
|
|
<
|
>







118431
118432
118433
118434
118435
118436
118437
118438
118439
118440
118441
118442
118443
118444
118445
118446
118447
118448
118449
118450
118451
118452
118453
118454
118455

118456
118457
118458
118459
118460
118461
118462
118463
118464
      pTerm->wtFlags |= TERM_CODED;
    }
  }

  return pLevel->notReady;
}

#ifdef WHERETRACE_ENABLED
/*
** Print the content of a WhereTerm object
*/
static void whereTermPrint(WhereTerm *pTerm, int iTerm){
  if( pTerm==0 ){
    sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
  }else{
    char zType[4];
    memcpy(zType, "...", 4);
    if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
    if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
    if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
    sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
                       iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
                       pTerm->eOperator);
    sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
  }

}
#endif

#ifdef WHERETRACE_ENABLED
/*
** Print a WhereLoop object for debugging purposes
*/
static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
  WhereInfo *pWInfo = pWC->pWInfo;
117167
117168
117169
117170
117171
117172
117173
117174
117175
117176
117177
117178
117179
117180
117181
117182
117183
117184
117185
117186
117187
117188
117189
117190
117191
117192
117193
117194
117195
117196
117197
117198
117199
117200
117201
117202
117203
117204
117205
117206
    }else{
      z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
    }
    sqlite3DebugPrintf(" %-19s", z);
    sqlite3_free(z);
  }
  if( p->wsFlags & WHERE_SKIPSCAN ){
    sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
  }else{
    sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
  }
  sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
  /* If the 0x100 bit of wheretracing is set, then show all of the constraint
  ** expressions in the WhereLoop.aLTerm[] array.
  */
  if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){  /* WHERETRACE 0x100 */
    int i;
    Vdbe *v = pWInfo->pParse->pVdbe;
    sqlite3ExplainBegin(v);
    for(i=0; i<p->nLTerm; i++){
      WhereTerm *pTerm = p->aLTerm[i];
      if( pTerm==0 ) continue;
      sqlite3ExplainPrintf(v, "  (%d) #%-2d ", i+1, (int)(pTerm-pWC->a));
      sqlite3ExplainPush(v);
      whereExplainTerm(v, pTerm);
      sqlite3ExplainPop(v);
      sqlite3ExplainNL(v);
    }
    sqlite3ExplainFinish(v);
    sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
  }
#endif
}
#endif

/*
** Convert bulk memory into a valid WhereLoop that can be passed
** to whereLoopClear harmlessly.
*/







|




<
<
<
<
|

<
<

|
<
<
<
<
<
<

<
<

<







118489
118490
118491
118492
118493
118494
118495
118496
118497
118498
118499
118500




118501
118502


118503
118504






118505


118506

118507
118508
118509
118510
118511
118512
118513
    }else{
      z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
    }
    sqlite3DebugPrintf(" %-19s", z);
    sqlite3_free(z);
  }
  if( p->wsFlags & WHERE_SKIPSCAN ){
    sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
  }else{
    sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
  }
  sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);




  if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
    int i;


    for(i=0; i<p->nLTerm; i++){
      whereTermPrint(p->aLTerm[i], i);






    }


  }

}
#endif

/*
** Convert bulk memory into a valid WhereLoop that can be passed
** to whereLoopClear harmlessly.
*/
117293
117294
117295
117296
117297
117298
117299
117300
117301
117302
117303

117304
117305
117306
117307
117308
117309
117310
117311


117312
117313
117314
117315
117316
117317

117318


117319
117320
117321
117322
117323

117324
117325
117326
117327
117328
117329
117330
      whereLoopDelete(db, p);
    }
    sqlite3DbFree(db, pWInfo);
  }
}

/*
** Return TRUE if both of the following are true:
**
**   (1)  X has the same or lower cost that Y
**   (2)  X is a proper subset of Y

**
** By "proper subset" we mean that X uses fewer WHERE clause terms
** than Y and that every WHERE clause term used by X is also used
** by Y.
**
** If X is a proper subset of Y then Y is a better choice and ought
** to have a lower cost.  This routine returns TRUE when that cost 
** relationship is inverted and needs to be adjusted.


*/
static int whereLoopCheaperProperSubset(
  const WhereLoop *pX,       /* First WhereLoop to compare */
  const WhereLoop *pY        /* Compare against this WhereLoop */
){
  int i, j;

  if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */


  if( pX->rRun >= pY->rRun ){
    if( pX->rRun > pY->rRun ) return 0;    /* X costs more than Y */
    if( pX->nOut > pY->nOut ) return 0;    /* X costs more than Y */
  }
  for(i=pX->nLTerm-1; i>=0; i--){

    for(j=pY->nLTerm-1; j>=0; j--){
      if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
    }
    if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
  }
  return 1;  /* All conditions meet */
}







|



>







|
>
>






>
|
>
>





>







118600
118601
118602
118603
118604
118605
118606
118607
118608
118609
118610
118611
118612
118613
118614
118615
118616
118617
118618
118619
118620
118621
118622
118623
118624
118625
118626
118627
118628
118629
118630
118631
118632
118633
118634
118635
118636
118637
118638
118639
118640
118641
118642
118643
118644
      whereLoopDelete(db, p);
    }
    sqlite3DbFree(db, pWInfo);
  }
}

/*
** Return TRUE if all of the following are true:
**
**   (1)  X has the same or lower cost that Y
**   (2)  X is a proper subset of Y
**   (3)  X skips at least as many columns as Y
**
** By "proper subset" we mean that X uses fewer WHERE clause terms
** than Y and that every WHERE clause term used by X is also used
** by Y.
**
** If X is a proper subset of Y then Y is a better choice and ought
** to have a lower cost.  This routine returns TRUE when that cost 
** relationship is inverted and needs to be adjusted.  The third rule
** was added because if X uses skip-scan less than Y it still might
** deserve a lower cost even if it is a proper subset of Y.
*/
static int whereLoopCheaperProperSubset(
  const WhereLoop *pX,       /* First WhereLoop to compare */
  const WhereLoop *pY        /* Compare against this WhereLoop */
){
  int i, j;
  if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
    return 0; /* X is not a subset of Y */
  }
  if( pY->nSkip > pX->nSkip ) return 0;
  if( pX->rRun >= pY->rRun ){
    if( pX->rRun > pY->rRun ) return 0;    /* X costs more than Y */
    if( pX->nOut > pY->nOut ) return 0;    /* X costs more than Y */
  }
  for(i=pX->nLTerm-1; i>=0; i--){
    if( pX->aLTerm[i]==0 ) continue;
    for(j=pY->nLTerm-1; j>=0; j--){
      if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
    }
    if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
  }
  return 1;  /* All conditions meet */
}
117338
117339
117340
117341
117342
117343
117344
117345
117346
117347
117348
117349
117350
117351
117352
117353
117354
117355
117356
117357
117358
117359
117360
117361
117362
117363
117364
117365
117366


117367
117368
117369
117370
117371


117372
117373
117374
117375
117376
117377
117378
**
**   (2) pTemplate costs more than any other WhereLoops for which pTemplate
**       is a proper subset.
**
** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
** WHERE clause terms than Y and that every WHERE clause term used by X is
** also used by Y.
**
** This adjustment is omitted for SKIPSCAN loops.  In a SKIPSCAN loop, the
** WhereLoop.nLTerm field is not an accurate measure of the number of WHERE
** clause terms covered, since some of the first nLTerm entries in aLTerm[]
** will be NULL (because they are skipped).  That makes it more difficult
** to compare the loops.  We could add extra code to do the comparison, and
** perhaps we will someday.  But SKIPSCAN is sufficiently uncommon, and this
** adjustment is sufficient minor, that it is very difficult to construct
** a test case where the extra code would improve the query plan.  Better
** to avoid the added complexity and just omit cost adjustments to SKIPSCAN
** loops.
*/
static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
  if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return;
  if( (pTemplate->wsFlags & WHERE_SKIPSCAN)!=0 ) return;
  for(; p; p=p->pNextLoop){
    if( p->iTab!=pTemplate->iTab ) continue;
    if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
    if( (p->wsFlags & WHERE_SKIPSCAN)!=0 ) continue;
    if( whereLoopCheaperProperSubset(p, pTemplate) ){
      /* Adjust pTemplate cost downward so that it is cheaper than its 
      ** subset p */


      pTemplate->rRun = p->rRun;
      pTemplate->nOut = p->nOut - 1;
    }else if( whereLoopCheaperProperSubset(pTemplate, p) ){
      /* Adjust pTemplate cost upward so that it is costlier than p since
      ** pTemplate is a proper subset of p */


      pTemplate->rRun = p->rRun;
      pTemplate->nOut = p->nOut + 1;
    }
  }
}

/*







<
<
<
<
<
<
<
<
<
<
<



<



<


|
>
>





>
>







118652
118653
118654
118655
118656
118657
118658











118659
118660
118661

118662
118663
118664

118665
118666
118667
118668
118669
118670
118671
118672
118673
118674
118675
118676
118677
118678
118679
118680
118681
118682
118683
**
**   (2) pTemplate costs more than any other WhereLoops for which pTemplate
**       is a proper subset.
**
** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
** WHERE clause terms than Y and that every WHERE clause term used by X is
** also used by Y.











*/
static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
  if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return;

  for(; p; p=p->pNextLoop){
    if( p->iTab!=pTemplate->iTab ) continue;
    if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;

    if( whereLoopCheaperProperSubset(p, pTemplate) ){
      /* Adjust pTemplate cost downward so that it is cheaper than its 
      ** subset p. */
      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
                       pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1));
      pTemplate->rRun = p->rRun;
      pTemplate->nOut = p->nOut - 1;
    }else if( whereLoopCheaperProperSubset(pTemplate, p) ){
      /* Adjust pTemplate cost upward so that it is costlier than p since
      ** pTemplate is a proper subset of p */
      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
                       pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut+1));
      pTemplate->rRun = p->rRun;
      pTemplate->nOut = p->nOut + 1;
    }
  }
}

/*
117409
117410
117411
117412
117413
117414
117415
117416
117417

117418
117419
117420
117421
117422
117423
117424
    /* whereLoopAddBtree() always generates and inserts the automatic index
    ** case first.  Hence compatible candidate WhereLoops never have a larger
    ** rSetup. Call this SETUP-INVARIANT */
    assert( p->rSetup>=pTemplate->rSetup );

    /* Any loop using an appliation-defined index (or PRIMARY KEY or
    ** UNIQUE constraint) with one or more == constraints is better
    ** than an automatic index. */
    if( (p->wsFlags & WHERE_AUTO_INDEX)!=0

     && (pTemplate->wsFlags & WHERE_INDEXED)!=0
     && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0
     && (p->prereq & pTemplate->prereq)==pTemplate->prereq
    ){
      break;
    }








|

>







118714
118715
118716
118717
118718
118719
118720
118721
118722
118723
118724
118725
118726
118727
118728
118729
118730
    /* whereLoopAddBtree() always generates and inserts the automatic index
    ** case first.  Hence compatible candidate WhereLoops never have a larger
    ** rSetup. Call this SETUP-INVARIANT */
    assert( p->rSetup>=pTemplate->rSetup );

    /* Any loop using an appliation-defined index (or PRIMARY KEY or
    ** UNIQUE constraint) with one or more == constraints is better
    ** than an automatic index. Unless it is a skip-scan. */
    if( (p->wsFlags & WHERE_AUTO_INDEX)!=0
     && (pTemplate->nSkip)==0
     && (pTemplate->wsFlags & WHERE_INDEXED)!=0
     && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0
     && (p->prereq & pTemplate->prereq)==pTemplate->prereq
    ){
      break;
    }

117505
117506
117507
117508
117509
117510
117511
117512
117513
117514
117515
117516
117517
117518
117519
117520
117521
117522
117523
117524
117525
117526
117527
117528
117529
117530
117531
117532
117533
117534
117535
117536
117537
117538
  ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate);

  if( ppPrev==0 ){
    /* There already exists a WhereLoop on the list that is better
    ** than pTemplate, so just ignore pTemplate */
#if WHERETRACE_ENABLED /* 0x8 */
    if( sqlite3WhereTrace & 0x8 ){
      sqlite3DebugPrintf("ins-noop: ");
      whereLoopPrint(pTemplate, pBuilder->pWC);
    }
#endif
    return SQLITE_OK;  
  }else{
    p = *ppPrev;
  }

  /* If we reach this point it means that either p[] should be overwritten
  ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
  ** WhereLoop and insert it.
  */
#if WHERETRACE_ENABLED /* 0x8 */
  if( sqlite3WhereTrace & 0x8 ){
    if( p!=0 ){
      sqlite3DebugPrintf("ins-del:  ");
      whereLoopPrint(p, pBuilder->pWC);
    }
    sqlite3DebugPrintf("ins-new:  ");
    whereLoopPrint(pTemplate, pBuilder->pWC);
  }
#endif
  if( p==0 ){
    /* Allocate a new WhereLoop to add to the end of the list */
    *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
    if( p==0 ) return SQLITE_NOMEM;







|















|


|







118811
118812
118813
118814
118815
118816
118817
118818
118819
118820
118821
118822
118823
118824
118825
118826
118827
118828
118829
118830
118831
118832
118833
118834
118835
118836
118837
118838
118839
118840
118841
118842
118843
118844
  ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate);

  if( ppPrev==0 ){
    /* There already exists a WhereLoop on the list that is better
    ** than pTemplate, so just ignore pTemplate */
#if WHERETRACE_ENABLED /* 0x8 */
    if( sqlite3WhereTrace & 0x8 ){
      sqlite3DebugPrintf("   skip: ");
      whereLoopPrint(pTemplate, pBuilder->pWC);
    }
#endif
    return SQLITE_OK;  
  }else{
    p = *ppPrev;
  }

  /* If we reach this point it means that either p[] should be overwritten
  ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
  ** WhereLoop and insert it.
  */
#if WHERETRACE_ENABLED /* 0x8 */
  if( sqlite3WhereTrace & 0x8 ){
    if( p!=0 ){
      sqlite3DebugPrintf("replace: ");
      whereLoopPrint(p, pBuilder->pWC);
    }
    sqlite3DebugPrintf("    add: ");
    whereLoopPrint(pTemplate, pBuilder->pWC);
  }
#endif
  if( p==0 ){
    /* Allocate a new WhereLoop to add to the end of the list */
    *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
    if( p==0 ) return SQLITE_NOMEM;
117548
117549
117550
117551
117552
117553
117554
117555
117556
117557
117558
117559
117560
117561
117562
117563
117564
117565
117566
117567
117568
117569
117570
117571
117572
117573
117574
117575





117576
117577







117578



117579





117580
117581
117582
117583
117584
117585
117586
117587
117588
117589
117590

117591
117592
117593
117594
117595
117596
117597
117598
117599
117600
117601
117602


117603
117604


117605
117606








117607
117608
117609
117610
117611
117612
117613
117614
117615
117616
117617
117618
117619
117620
117621
117622
117623
      ppTail = whereLoopFindLesser(ppTail, pTemplate);
      if( ppTail==0 ) break;
      pToDel = *ppTail;
      if( pToDel==0 ) break;
      *ppTail = pToDel->pNextLoop;
#if WHERETRACE_ENABLED /* 0x8 */
      if( sqlite3WhereTrace & 0x8 ){
        sqlite3DebugPrintf("ins-del:  ");
        whereLoopPrint(pToDel, pBuilder->pWC);
      }
#endif
      whereLoopDelete(db, pToDel);
    }
  }
  whereLoopXfer(db, p, pTemplate);
  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
    Index *pIndex = p->u.btree.pIndex;
    if( pIndex && pIndex->tnum==0 ){
      p->u.btree.pIndex = 0;
    }
  }
  return SQLITE_OK;
}

/*
** Adjust the WhereLoop.nOut value downward to account for terms of the
** WHERE clause that reference the loop but which are not used by an
** index.





**
** In the current implementation, the first extra WHERE clause term reduces







** the number of output rows by a factor of 10 and each additional term



** reduces the number of output rows by sqrt(2).





*/
static void whereLoopOutputAdjust(
  WhereClause *pWC,      /* The WHERE clause */
  WhereLoop *pLoop,      /* The loop to adjust downward */
  LogEst nRow            /* Number of rows in the entire table */
){
  WhereTerm *pTerm, *pX;
  Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
  int i, j;
  int nEq = 0;    /* Number of = constraints not within likely()/unlikely() */


  for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
    if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
    if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
    if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
    for(j=pLoop->nLTerm-1; j>=0; j--){
      pX = pLoop->aLTerm[j];
      if( pX==0 ) continue;
      if( pX==pTerm ) break;
      if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
    }
    if( j<0 ){
      if( pTerm->truthProb<=0 ){


        pLoop->nOut += pTerm->truthProb;
      }else{


        pLoop->nOut--;
        if( pTerm->eOperator&WO_EQ ) nEq++;








      }
    }
  }
  /* TUNING:  If there is at least one equality constraint in the WHERE
  ** clause that does not have a likelihood() explicitly assigned to it
  ** then do not let the estimated number of output rows exceed half 
  ** the number of rows in the table. */
  if( nEq && pLoop->nOut>nRow-10 ){
    pLoop->nOut = nRow - 10;
  }
}

/*
** Adjust the cost C by the costMult facter T.  This only occurs if
** compiled with -DSQLITE_ENABLE_COSTMULT
*/
#ifdef SQLITE_ENABLE_COSTMULT







|




















>
>
>
>
>

|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>








|
|

>












>
>


>
>

|
>
>
>
>
>
>
>
>



<
<
<
<
<
|
<







118854
118855
118856
118857
118858
118859
118860
118861
118862
118863
118864
118865
118866
118867
118868
118869
118870
118871
118872
118873
118874
118875
118876
118877
118878
118879
118880
118881
118882
118883
118884
118885
118886
118887
118888
118889
118890
118891
118892
118893
118894
118895
118896
118897
118898
118899
118900
118901
118902
118903
118904
118905
118906
118907
118908
118909
118910
118911
118912
118913
118914
118915
118916
118917
118918
118919
118920
118921
118922
118923
118924
118925
118926
118927
118928
118929
118930
118931
118932
118933
118934
118935
118936
118937
118938
118939
118940
118941
118942
118943
118944
118945
118946
118947
118948





118949

118950
118951
118952
118953
118954
118955
118956
      ppTail = whereLoopFindLesser(ppTail, pTemplate);
      if( ppTail==0 ) break;
      pToDel = *ppTail;
      if( pToDel==0 ) break;
      *ppTail = pToDel->pNextLoop;
#if WHERETRACE_ENABLED /* 0x8 */
      if( sqlite3WhereTrace & 0x8 ){
        sqlite3DebugPrintf(" delete: ");
        whereLoopPrint(pToDel, pBuilder->pWC);
      }
#endif
      whereLoopDelete(db, pToDel);
    }
  }
  whereLoopXfer(db, p, pTemplate);
  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
    Index *pIndex = p->u.btree.pIndex;
    if( pIndex && pIndex->tnum==0 ){
      p->u.btree.pIndex = 0;
    }
  }
  return SQLITE_OK;
}

/*
** Adjust the WhereLoop.nOut value downward to account for terms of the
** WHERE clause that reference the loop but which are not used by an
** index.
*
** For every WHERE clause term that is not used by the index
** and which has a truth probability assigned by one of the likelihood(),
** likely(), or unlikely() SQL functions, reduce the estimated number
** of output rows by the probability specified.
**
** TUNING:  For every WHERE clause term that is not used by the index
** and which does not have an assigned truth probability, heuristics
** described below are used to try to estimate the truth probability.
** TODO --> Perhaps this is something that could be improved by better
** table statistics.
**
** Heuristic 1:  Estimate the truth probability as 93.75%.  The 93.75%
** value corresponds to -1 in LogEst notation, so this means decrement
** the WhereLoop.nOut field for every such WHERE clause term.
**
** Heuristic 2:  If there exists one or more WHERE clause terms of the
** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the
** final output row estimate is no greater than 1/4 of the total number
** of rows in the table.  In other words, assume that x==EXPR will filter
** out at least 3 out of 4 rows.  If EXPR is -1 or 0 or 1, then maybe the
** "x" column is boolean or else -1 or 0 or 1 is a common default value
** on the "x" column and so in that case only cap the output row estimate
** at 1/2 instead of 1/4.
*/
static void whereLoopOutputAdjust(
  WhereClause *pWC,      /* The WHERE clause */
  WhereLoop *pLoop,      /* The loop to adjust downward */
  LogEst nRow            /* Number of rows in the entire table */
){
  WhereTerm *pTerm, *pX;
  Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
  int i, j, k;
  LogEst iReduce = 0;    /* pLoop->nOut should not exceed nRow-iReduce */

  assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
  for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
    if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
    if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
    if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
    for(j=pLoop->nLTerm-1; j>=0; j--){
      pX = pLoop->aLTerm[j];
      if( pX==0 ) continue;
      if( pX==pTerm ) break;
      if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
    }
    if( j<0 ){
      if( pTerm->truthProb<=0 ){
        /* If a truth probability is specified using the likelihood() hints,
        ** then use the probability provided by the application. */
        pLoop->nOut += pTerm->truthProb;
      }else{
        /* In the absence of explicit truth probabilities, use heuristics to
        ** guess a reasonable truth probability. */
        pLoop->nOut--;
        if( pTerm->eOperator&WO_EQ ){
          Expr *pRight = pTerm->pExpr->pRight;
          if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
            k = 10;
          }else{
            k = 20;
          }
          if( iReduce<k ) iReduce = k;
        }
      }
    }
  }





  if( pLoop->nOut > nRow-iReduce )  pLoop->nOut = nRow - iReduce;

}

/*
** Adjust the cost C by the costMult facter T.  This only occurs if
** compiled with -DSQLITE_ENABLE_COSTMULT
*/
#ifdef SQLITE_ENABLE_COSTMULT
117650
117651
117652
117653
117654
117655
117656
117657
117658
117659
117660
117661
117662
117663
117664
  WhereLoop *pNew;                /* Template WhereLoop under construction */
  WhereTerm *pTerm;               /* A WhereTerm under consideration */
  int opMask;                     /* Valid operators for constraints */
  WhereScan scan;                 /* Iterator for WHERE terms */
  Bitmask saved_prereq;           /* Original value of pNew->prereq */
  u16 saved_nLTerm;               /* Original value of pNew->nLTerm */
  u16 saved_nEq;                  /* Original value of pNew->u.btree.nEq */
  u16 saved_nSkip;                /* Original value of pNew->u.btree.nSkip */
  u32 saved_wsFlags;              /* Original value of pNew->wsFlags */
  LogEst saved_nOut;              /* Original value of pNew->nOut */
  int iCol;                       /* Index of the column in the table */
  int rc = SQLITE_OK;             /* Return code */
  LogEst rSize;                   /* Number of rows in the table */
  LogEst rLogSize;                /* Logarithm of table size */
  WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */







|







118983
118984
118985
118986
118987
118988
118989
118990
118991
118992
118993
118994
118995
118996
118997
  WhereLoop *pNew;                /* Template WhereLoop under construction */
  WhereTerm *pTerm;               /* A WhereTerm under consideration */
  int opMask;                     /* Valid operators for constraints */
  WhereScan scan;                 /* Iterator for WHERE terms */
  Bitmask saved_prereq;           /* Original value of pNew->prereq */
  u16 saved_nLTerm;               /* Original value of pNew->nLTerm */
  u16 saved_nEq;                  /* Original value of pNew->u.btree.nEq */
  u16 saved_nSkip;                /* Original value of pNew->nSkip */
  u32 saved_wsFlags;              /* Original value of pNew->wsFlags */
  LogEst saved_nOut;              /* Original value of pNew->nOut */
  int iCol;                       /* Index of the column in the table */
  int rc = SQLITE_OK;             /* Return code */
  LogEst rSize;                   /* Number of rows in the table */
  LogEst rLogSize;                /* Logarithm of table size */
  WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
117679
117680
117681
117682
117683
117684
117685
117686
117687
117688
117689
117690
117691
117692
117693
117694
117695
117696
117697
117698
117699
117700
117701
117702
117703
117704
117705
117706
117707
117708
117709
117710
117711
117712
117713
117714
117715
117716
117717
117718
117719
117720
117721
117722
117723
117724
117725
117726
117727
117728
117729
117730
117731
117732
117733
117734
117735

  assert( pNew->u.btree.nEq<pProbe->nColumn );
  iCol = pProbe->aiColumn[pNew->u.btree.nEq];

  pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
                        opMask, pProbe);
  saved_nEq = pNew->u.btree.nEq;
  saved_nSkip = pNew->u.btree.nSkip;
  saved_nLTerm = pNew->nLTerm;
  saved_wsFlags = pNew->wsFlags;
  saved_prereq = pNew->prereq;
  saved_nOut = pNew->nOut;
  pNew->rSetup = 0;
  rSize = pProbe->aiRowLogEst[0];
  rLogSize = estLog(rSize);

  /* Consider using a skip-scan if there are no WHERE clause constraints
  ** available for the left-most terms of the index, and if the average
  ** number of repeats in the left-most terms is at least 18. 
  **
  ** The magic number 18 is selected on the basis that scanning 17 rows
  ** is almost always quicker than an index seek (even though if the index
  ** contains fewer than 2^17 rows we assume otherwise in other parts of
  ** the code). And, even if it is not, it should not be too much slower. 
  ** On the other hand, the extra seeks could end up being significantly
  ** more expensive.  */
  assert( 42==sqlite3LogEst(18) );
  if( saved_nEq==saved_nSkip
   && saved_nEq+1<pProbe->nKeyCol
   && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
   && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
  ){
    LogEst nIter;
    pNew->u.btree.nEq++;
    pNew->u.btree.nSkip++;
    pNew->aLTerm[pNew->nLTerm++] = 0;
    pNew->wsFlags |= WHERE_SKIPSCAN;
    nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
    if( pTerm ){
      /* TUNING:  When estimating skip-scan for a term that is also indexable,
      ** increase the cost of the skip-scan by 2x, to make it a little less
      ** desirable than the regular index lookup. */
      nIter += 10;  assert( 10==sqlite3LogEst(2) );
    }
    pNew->nOut -= nIter;
    whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
    pNew->nOut = saved_nOut;
    pNew->u.btree.nEq = saved_nEq;
    pNew->u.btree.nSkip = saved_nSkip;
  }
  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    u16 eOp = pTerm->eOperator;   /* Shorthand for pTerm->eOperator */
    LogEst rCostIdx;
    LogEst nOutUnadjusted;        /* nOut before IN() and WHERE adjustments */
    int nIn = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    int nRecValid = pBuilder->nRecValid;







|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







119012
119013
119014
119015
119016
119017
119018
119019
119020
119021
119022
119023
119024
119025
119026



































119027
119028
119029
119030
119031
119032
119033

  assert( pNew->u.btree.nEq<pProbe->nColumn );
  iCol = pProbe->aiColumn[pNew->u.btree.nEq];

  pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
                        opMask, pProbe);
  saved_nEq = pNew->u.btree.nEq;
  saved_nSkip = pNew->nSkip;
  saved_nLTerm = pNew->nLTerm;
  saved_wsFlags = pNew->wsFlags;
  saved_prereq = pNew->prereq;
  saved_nOut = pNew->nOut;
  pNew->rSetup = 0;
  rSize = pProbe->aiRowLogEst[0];
  rLogSize = estLog(rSize);



































  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    u16 eOp = pTerm->eOperator;   /* Shorthand for pTerm->eOperator */
    LogEst rCostIdx;
    LogEst nOutUnadjusted;        /* nOut before IN() and WHERE adjustments */
    int nIn = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    int nRecValid = pBuilder->nRecValid;
117816
117817
117818
117819
117820
117821
117822
117823
117824
117825
117826
117827
117828
117829
117830
        pNew->nOut -= nIn;
      }else{
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
        tRowcnt nOut = 0;
        if( nInMul==0 
         && pProbe->nSample 
         && pNew->u.btree.nEq<=pProbe->nSampleCol
         && OptimizationEnabled(db, SQLITE_Stat3) 
         && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
        ){
          Expr *pExpr = pTerm->pExpr;
          if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
            testcase( eOp & WO_EQ );
            testcase( eOp & WO_ISNULL );
            rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);







<







119114
119115
119116
119117
119118
119119
119120

119121
119122
119123
119124
119125
119126
119127
        pNew->nOut -= nIn;
      }else{
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
        tRowcnt nOut = 0;
        if( nInMul==0 
         && pProbe->nSample 
         && pNew->u.btree.nEq<=pProbe->nSampleCol

         && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
        ){
          Expr *pExpr = pTerm->pExpr;
          if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
            testcase( eOp & WO_EQ );
            testcase( eOp & WO_ISNULL );
            rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
117884
117885
117886
117887
117888
117889
117890
117891
117892
117893
117894



































117895
117896
117897
117898
117899
117900
117901
    pNew->nOut = saved_nOut;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    pBuilder->nRecValid = nRecValid;
#endif
  }
  pNew->prereq = saved_prereq;
  pNew->u.btree.nEq = saved_nEq;
  pNew->u.btree.nSkip = saved_nSkip;
  pNew->wsFlags = saved_wsFlags;
  pNew->nOut = saved_nOut;
  pNew->nLTerm = saved_nLTerm;



































  return rc;
}

/*
** Return True if it is possible that pIndex might be useful in
** implementing the ORDER BY clause in pBuilder.
**







|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







119181
119182
119183
119184
119185
119186
119187
119188
119189
119190
119191
119192
119193
119194
119195
119196
119197
119198
119199
119200
119201
119202
119203
119204
119205
119206
119207
119208
119209
119210
119211
119212
119213
119214
119215
119216
119217
119218
119219
119220
119221
119222
119223
119224
119225
119226
119227
119228
119229
119230
119231
119232
119233
    pNew->nOut = saved_nOut;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    pBuilder->nRecValid = nRecValid;
#endif
  }
  pNew->prereq = saved_prereq;
  pNew->u.btree.nEq = saved_nEq;
  pNew->nSkip = saved_nSkip;
  pNew->wsFlags = saved_wsFlags;
  pNew->nOut = saved_nOut;
  pNew->nLTerm = saved_nLTerm;

  /* Consider using a skip-scan if there are no WHERE clause constraints
  ** available for the left-most terms of the index, and if the average
  ** number of repeats in the left-most terms is at least 18. 
  **
  ** The magic number 18 is selected on the basis that scanning 17 rows
  ** is almost always quicker than an index seek (even though if the index
  ** contains fewer than 2^17 rows we assume otherwise in other parts of
  ** the code). And, even if it is not, it should not be too much slower. 
  ** On the other hand, the extra seeks could end up being significantly
  ** more expensive.  */
  assert( 42==sqlite3LogEst(18) );
  if( saved_nEq==saved_nSkip
   && saved_nEq+1<pProbe->nKeyCol
   && pProbe->noSkipScan==0
   && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
   && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
  ){
    LogEst nIter;
    pNew->u.btree.nEq++;
    pNew->nSkip++;
    pNew->aLTerm[pNew->nLTerm++] = 0;
    pNew->wsFlags |= WHERE_SKIPSCAN;
    nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
    pNew->nOut -= nIter;
    /* TUNING:  Because uncertainties in the estimates for skip-scan queries,
    ** add a 1.375 fudge factor to make skip-scan slightly less likely. */
    nIter += 5;
    whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
    pNew->nOut = saved_nOut;
    pNew->u.btree.nEq = saved_nEq;
    pNew->nSkip = saved_nSkip;
    pNew->wsFlags = saved_wsFlags;
  }

  return rc;
}

/*
** Return True if it is possible that pIndex might be useful in
** implementing the ORDER BY clause in pBuilder.
**
118066
118067
118068
118069
118070
118071
118072
118073
118074
118075
118076
118077
118078
118079





118080



118081
118082
118083
118084
118085
118086
118087
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
        pNew->u.btree.nEq = 1;
        pNew->u.btree.nSkip = 0;
        pNew->u.btree.pIndex = 0;
        pNew->nLTerm = 1;
        pNew->aLTerm[0] = pTerm;
        /* TUNING: One-time cost for computing the automatic index is
        ** approximately 7*N*log2(N) where N is the number of rows in
        ** the table being indexed. */





        pNew->rSetup = rLogSize + rSize + 28;  assert( 28==sqlite3LogEst(7) );



        ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
        /* TUNING: Each index lookup yields 20 rows in the table.  This
        ** is more than the usual guess of 10 rows, since we have no way
        ** of knowing how selective the index will ultimately be.  It would
        ** not be unreasonable to make this value much larger. */
        pNew->nOut = 43;  assert( 43==sqlite3LogEst(20) );
        pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);







|




|
|
>
>
>
>
>
|
>
>
>







119398
119399
119400
119401
119402
119403
119404
119405
119406
119407
119408
119409
119410
119411
119412
119413
119414
119415
119416
119417
119418
119419
119420
119421
119422
119423
119424
119425
119426
119427
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
        pNew->u.btree.nEq = 1;
        pNew->nSkip = 0;
        pNew->u.btree.pIndex = 0;
        pNew->nLTerm = 1;
        pNew->aLTerm[0] = pTerm;
        /* TUNING: One-time cost for computing the automatic index is
        ** estimated to be X*N*log2(N) where N is the number of rows in
        ** the table being indexed and where X is 7 (LogEst=28) for normal
        ** tables or 1.375 (LogEst=4) for views and subqueries.  The value
        ** of X is smaller for views and subqueries so that the query planner
        ** will be more aggressive about generating automatic indexes for
        ** those objects, since there is no opportunity to add schema
        ** indexes on subqueries and views. */
        pNew->rSetup = rLogSize + rSize + 4;
        if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
          pNew->rSetup += 24;
        }
        ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
        /* TUNING: Each index lookup yields 20 rows in the table.  This
        ** is more than the usual guess of 10 rows, since we have no way
        ** of knowing how selective the index will ultimately be.  It would
        ** not be unreasonable to make this value much larger. */
        pNew->nOut = 43;  assert( 43==sqlite3LogEst(20) );
        pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
118099
118100
118101
118102
118103
118104
118105
118106
118107
118108
118109
118110
118111
118112
118113
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
      continue;  /* Partial index inappropriate for this query */
    }
    rSize = pProbe->aiRowLogEst[0];
    pNew->u.btree.nEq = 0;
    pNew->u.btree.nSkip = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;
    b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);







|







119439
119440
119441
119442
119443
119444
119445
119446
119447
119448
119449
119450
119451
119452
119453
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
      continue;  /* Partial index inappropriate for this query */
    }
    rSize = pProbe->aiRowLogEst[0];
    pNew->u.btree.nEq = 0;
    pNew->nSkip = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;
    b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
118361
118362
118363
118364
118365
118366
118367
118368
118369
118370
118371
118372
118373
118374
118375
118376
118377
118378
118379
118380
118381
118382
118383
118384
118385
118386
118387
118388

118389
118390
118391
118392
118393
118394
118395
118396
118397
118398
118399
118400
118401
118402









118403
118404
118405
118406
118407
118408
118409
118410



118411
118412
118413
118414
118415
118416
118417
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur;
  struct SrcList_item *pItem;
  
  pWC = pBuilder->pWC;
  if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;
  memset(&sSum, 0, sizeof(sSum));
  pItem = pWInfo->pTabList->a + pNew->iTab;
  iCur = pItem->iCursor;

  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
    if( (pTerm->eOperator & WO_OR)!=0
     && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 
    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
      WhereTerm *pOrTerm;
      int once = 1;
      int i, j;
    
      sSubBuild = *pBuilder;
      sSubBuild.pOrderBy = 0;
      sSubBuild.pOrSet = &sCur;


      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        if( (pOrTerm->eOperator & WO_AND)!=0 ){
          sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
        }else if( pOrTerm->leftCursor==iCur ){
          tempWC.pWInfo = pWC->pWInfo;
          tempWC.pOuter = pWC;
          tempWC.op = TK_AND;
          tempWC.nTerm = 1;
          tempWC.a = pOrTerm;
          sSubBuild.pWC = &tempWC;
        }else{
          continue;
        }
        sCur.n = 0;









#ifndef SQLITE_OMIT_VIRTUALTABLE
        if( IsVirtual(pItem->pTab) ){
          rc = whereLoopAddVirtual(&sSubBuild, mExtra);
        }else
#endif
        {
          rc = whereLoopAddBtree(&sSubBuild, mExtra);
        }



        assert( rc==SQLITE_OK || sCur.n==0 );
        if( sCur.n==0 ){
          sSum.n = 0;
          break;
        }else if( once ){
          whereOrMove(&sSum, &sCur);
          once = 0;







<




















>














>
>
>
>
>
>
>
>
>








>
>
>







119701
119702
119703
119704
119705
119706
119707

119708
119709
119710
119711
119712
119713
119714
119715
119716
119717
119718
119719
119720
119721
119722
119723
119724
119725
119726
119727
119728
119729
119730
119731
119732
119733
119734
119735
119736
119737
119738
119739
119740
119741
119742
119743
119744
119745
119746
119747
119748
119749
119750
119751
119752
119753
119754
119755
119756
119757
119758
119759
119760
119761
119762
119763
119764
119765
119766
119767
119768
119769
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur;
  struct SrcList_item *pItem;
  
  pWC = pBuilder->pWC;

  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;
  memset(&sSum, 0, sizeof(sSum));
  pItem = pWInfo->pTabList->a + pNew->iTab;
  iCur = pItem->iCursor;

  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
    if( (pTerm->eOperator & WO_OR)!=0
     && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 
    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
      WhereTerm *pOrTerm;
      int once = 1;
      int i, j;
    
      sSubBuild = *pBuilder;
      sSubBuild.pOrderBy = 0;
      sSubBuild.pOrSet = &sCur;

      WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        if( (pOrTerm->eOperator & WO_AND)!=0 ){
          sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
        }else if( pOrTerm->leftCursor==iCur ){
          tempWC.pWInfo = pWC->pWInfo;
          tempWC.pOuter = pWC;
          tempWC.op = TK_AND;
          tempWC.nTerm = 1;
          tempWC.a = pOrTerm;
          sSubBuild.pWC = &tempWC;
        }else{
          continue;
        }
        sCur.n = 0;
#ifdef WHERETRACE_ENABLED
        WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", 
                   (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
        if( sqlite3WhereTrace & 0x400 ){
          for(i=0; i<sSubBuild.pWC->nTerm; i++){
            whereTermPrint(&sSubBuild.pWC->a[i], i);
          }
        }
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
        if( IsVirtual(pItem->pTab) ){
          rc = whereLoopAddVirtual(&sSubBuild, mExtra);
        }else
#endif
        {
          rc = whereLoopAddBtree(&sSubBuild, mExtra);
        }
        if( rc==SQLITE_OK ){
          rc = whereLoopAddOr(&sSubBuild, mExtra);
        }
        assert( rc==SQLITE_OK || sCur.n==0 );
        if( sCur.n==0 ){
          sSum.n = 0;
          break;
        }else if( once ){
          whereOrMove(&sSum, &sCur);
          once = 0;
118448
118449
118450
118451
118452
118453
118454

118455
118456
118457
118458
118459
118460
118461
        ** the planner may elect to "OR" together a full-table scan and an
        ** index lookup. And other similarly odd results.  */
        pNew->rRun = sSum.a[i].rRun + 1;
        pNew->nOut = sSum.a[i].nOut;
        pNew->prereq = sSum.a[i].prereq;
        rc = whereLoopInsert(pBuilder, pNew);
      }

    }
  }
  return rc;
}

/*
** Add all WhereLoop objects for all tables 







>







119800
119801
119802
119803
119804
119805
119806
119807
119808
119809
119810
119811
119812
119813
119814
        ** the planner may elect to "OR" together a full-table scan and an
        ** index lookup. And other similarly odd results.  */
        pNew->rRun = sSum.a[i].rRun + 1;
        pNew->nOut = sSum.a[i].nOut;
        pNew->prereq = sSum.a[i].prereq;
        rc = whereLoopInsert(pBuilder, pNew);
      }
      WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm));
    }
  }
  return rc;
}

/*
** Add all WhereLoop objects for all tables 
118636
118637
118638
118639
118640
118641
118642
118643
118644
118645
118646
118647
118648
118649
118650
      rev = revSet = 0;
      distinctColumns = 0;
      for(j=0; j<nColumn; j++){
        u8 bOnce;   /* True to run the ORDER BY search loop */

        /* Skip over == and IS NULL terms */
        if( j<pLoop->u.btree.nEq
         && pLoop->u.btree.nSkip==0
         && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
        ){
          if( i & WO_ISNULL ){
            testcase( isOrderDistinct );
            isOrderDistinct = 0;
          }
          continue;  







|







119989
119990
119991
119992
119993
119994
119995
119996
119997
119998
119999
120000
120001
120002
120003
      rev = revSet = 0;
      distinctColumns = 0;
      for(j=0; j<nColumn; j++){
        u8 bOnce;   /* True to run the ORDER BY search loop */

        /* Skip over == and IS NULL terms */
        if( j<pLoop->u.btree.nEq
         && pLoop->nSkip==0
         && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
        ){
          if( i & WO_ISNULL ){
            testcase( isOrderDistinct );
            isOrderDistinct = 0;
          }
          continue;  
118691
118692
118693
118694
118695
118696
118697
118698
118699
118700
118701
118702
118703
118704
118705
            pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
            if( !pColl ) pColl = db->pDfltColl;
            if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
          }
          isMatch = 1;
          break;
        }
        if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
          /* Make sure the sort order is compatible in an ORDER BY clause.
          ** Sort order is irrelevant for a GROUP BY clause. */
          if( revSet ){
            if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
          }else{
            rev = revIdx ^ pOrderBy->a[i].sortOrder;
            if( rev ) *pRevMask |= MASKBIT(iLoop);







|







120044
120045
120046
120047
120048
120049
120050
120051
120052
120053
120054
120055
120056
120057
120058
            pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
            if( !pColl ) pColl = db->pDfltColl;
            if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
          }
          isMatch = 1;
          break;
        }
        if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
          /* Make sure the sort order is compatible in an ORDER BY clause.
          ** Sort order is irrelevant for a GROUP BY clause. */
          if( revSet ){
            if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
          }else{
            rev = revIdx ^ pOrderBy->a[i].sortOrder;
            if( rev ) *pRevMask |= MASKBIT(iLoop);
119090
119091
119092
119093
119094
119095
119096
119097
119098
119099
119100
119101
119102
119103
119104
            }
          }
        }
      }
    }

#ifdef WHERETRACE_ENABLED  /* >=2 */
    if( sqlite3WhereTrace>=2 ){
      sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
      for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
        sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
           wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
           pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?');
        if( pTo->isOrdered>0 ){
          sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);







|







120443
120444
120445
120446
120447
120448
120449
120450
120451
120452
120453
120454
120455
120456
120457
            }
          }
        }
      }
    }

#ifdef WHERETRACE_ENABLED  /* >=2 */
    if( sqlite3WhereTrace & 0x02 ){
      sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
      for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
        sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
           wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
           pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?');
        if( pTo->isOrdered>0 ){
          sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
119156
119157
119158
119159
119160
119161
119162
119163
119164
119165
119166
119167

119168


119169
119170
119171
119172
119173
119174
119175
      pWInfo->nOBSat = pFrom->isOrdered;
      if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
      pWInfo->revMask = pFrom->revLoop;
    }
    if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
        && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
    ){
      Bitmask notUsed = 0;
      int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, 
          pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed
      );
      assert( pWInfo->sorted==0 );

      pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr);


    }
  }


  pWInfo->nRowOut = pFrom->nRow;

  /* Free temporary memory and return success */







|

|


>
|
>
>







120509
120510
120511
120512
120513
120514
120515
120516
120517
120518
120519
120520
120521
120522
120523
120524
120525
120526
120527
120528
120529
120530
120531
      pWInfo->nOBSat = pFrom->isOrdered;
      if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
      pWInfo->revMask = pFrom->revLoop;
    }
    if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
        && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
    ){
      Bitmask revMask = 0;
      int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, 
          pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
      );
      assert( pWInfo->sorted==0 );
      if( nOrder==pWInfo->pOrderBy->nExpr ){
        pWInfo->sorted = 1;
        pWInfo->revMask = revMask;
      }
    }
  }


  pWInfo->nRowOut = pFrom->nRow;

  /* Free temporary memory and return success */
119206
119207
119208
119209
119210
119211
119212
119213
119214
119215
119216
119217
119218
119219
119220
119221
119222
119223
119224
119225
119226
119227
119228
119229
119230
119231
119232
  pTab = pItem->pTab;
  if( IsVirtual(pTab) ) return 0;
  if( pItem->zIndex ) return 0;
  iCur = pItem->iCursor;
  pWC = &pWInfo->sWC;
  pLoop = pBuilder->pNew;
  pLoop->wsFlags = 0;
  pLoop->u.btree.nSkip = 0;
  pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
  if( pTerm ){
    pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
    pLoop->aLTerm[0] = pTerm;
    pLoop->nLTerm = 1;
    pLoop->u.btree.nEq = 1;
    /* TUNING: Cost of a rowid lookup is 10 */
    pLoop->rRun = 33;  /* 33==sqlite3LogEst(10) */
  }else{
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pLoop->aLTermSpace==pLoop->aLTerm );
      assert( ArraySize(pLoop->aLTermSpace)==4 );
      if( !IsUniqueIndex(pIdx)
       || pIdx->pPartIdxWhere!=0 
       || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) 
      ) continue;
      for(j=0; j<pIdx->nKeyCol; j++){
        pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
        if( pTerm==0 ) break;







|











<







120562
120563
120564
120565
120566
120567
120568
120569
120570
120571
120572
120573
120574
120575
120576
120577
120578
120579
120580

120581
120582
120583
120584
120585
120586
120587
  pTab = pItem->pTab;
  if( IsVirtual(pTab) ) return 0;
  if( pItem->zIndex ) return 0;
  iCur = pItem->iCursor;
  pWC = &pWInfo->sWC;
  pLoop = pBuilder->pNew;
  pLoop->wsFlags = 0;
  pLoop->nSkip = 0;
  pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
  if( pTerm ){
    pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
    pLoop->aLTerm[0] = pTerm;
    pLoop->nLTerm = 1;
    pLoop->u.btree.nEq = 1;
    /* TUNING: Cost of a rowid lookup is 10 */
    pLoop->rRun = 33;  /* 33==sqlite3LogEst(10) */
  }else{
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pLoop->aLTermSpace==pLoop->aLTerm );

      if( !IsUniqueIndex(pIdx)
       || pIdx->pPartIdxWhere!=0 
       || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) 
      ) continue;
      for(j=0; j<pIdx->nKeyCol; j++){
        pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
        if( pTerm==0 ) break;
119514
119515
119516
119517
119518
119519
119520

119521
119522
119523
119524
119525
119526
119527
119528
119529
119530
119531
119532
119533
119534
119535
119536
119537

119538
119539
119540
119541
119542
119543
119544
      pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
      pWInfo->pOrderBy = pResultSet;
    }
  }

  /* Construct the WhereLoop objects */
  WHERETRACE(0xffff,("*** Optimizer Start ***\n"));

  /* Display all terms of the WHERE clause */
#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
  if( sqlite3WhereTrace & 0x100 ){
    int i;
    Vdbe *v = pParse->pVdbe;
    sqlite3ExplainBegin(v);
    for(i=0; i<sWLB.pWC->nTerm; i++){
      sqlite3ExplainPrintf(v, "#%-2d ", i);
      sqlite3ExplainPush(v);
      whereExplainTerm(v, &sWLB.pWC->a[i]);
      sqlite3ExplainPop(v);
      sqlite3ExplainNL(v);
    }
    sqlite3ExplainFinish(v);
    sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
  }
#endif

  if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
    rc = whereLoopAddAll(&sWLB);
    if( rc ) goto whereBeginError;
  
    /* Display all of the WhereLoop objects if wheretrace is enabled */
#ifdef WHERETRACE_ENABLED /* !=0 */
    if( sqlite3WhereTrace ){







>

<


<
<

<
<
|
<
<

<
<


>







120869
120870
120871
120872
120873
120874
120875
120876
120877

120878
120879


120880


120881


120882


120883
120884
120885
120886
120887
120888
120889
120890
120891
120892
      pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
      pWInfo->pOrderBy = pResultSet;
    }
  }

  /* Construct the WhereLoop objects */
  WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
#if defined(WHERETRACE_ENABLED)
  /* Display all terms of the WHERE clause */

  if( sqlite3WhereTrace & 0x100 ){
    int i;


    for(i=0; i<sWLB.pWC->nTerm; i++){


      whereTermPrint(&sWLB.pWC->a[i], i);


    }


  }
#endif

  if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
    rc = whereLoopAddAll(&sWLB);
    if( rc ) goto whereBeginError;
  
    /* Display all of the WhereLoop objects if wheretrace is enabled */
#ifdef WHERETRACE_ENABLED /* !=0 */
    if( sqlite3WhereTrace ){
119734
119735
119736
119737
119738
119739
119740


119741

119742
119743
119744
119745
119746
119747
119748

119749

119750
119751
119752



119753
119754
119755
119756
119757
119758
119759

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(ii=0; ii<nTabList; ii++){


    pLevel = &pWInfo->a[ii];

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
      constructAutomaticIndex(pParse, &pWInfo->sWC,
                &pTabList->a[pLevel->iFrom], notReady, pLevel);
      if( db->mallocFailed ) goto whereBeginError;
    }
#endif

    explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);

    pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
    notReady = codeOneLoopStart(pWInfo, ii, notReady);
    pWInfo->iContinue = pLevel->addrCont;



  }

  /* Done. */
  VdbeModuleComment((v, "Begin WHERE-core"));
  return pWInfo;

  /* Jump here if malloc fails */







>
>

>







>
|
>



>
>
>







121082
121083
121084
121085
121086
121087
121088
121089
121090
121091
121092
121093
121094
121095
121096
121097
121098
121099
121100
121101
121102
121103
121104
121105
121106
121107
121108
121109
121110
121111
121112
121113
121114
121115

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(ii=0; ii<nTabList; ii++){
    int addrExplain;
    int wsFlags;
    pLevel = &pWInfo->a[ii];
    wsFlags = pLevel->pWLoop->wsFlags;
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
      constructAutomaticIndex(pParse, &pWInfo->sWC,
                &pTabList->a[pLevel->iFrom], notReady, pLevel);
      if( db->mallocFailed ) goto whereBeginError;
    }
#endif
    addrExplain = explainOneScan(
        pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
    );
    pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
    notReady = codeOneLoopStart(pWInfo, ii, notReady);
    pWInfo->iContinue = pLevel->addrCont;
    if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_ONETABLE_ONLY)==0 ){
      addScanStatus(v, pTabList, pLevel, addrExplain);
    }
  }

  /* Done. */
  VdbeModuleComment((v, "Begin WHERE-core"));
  return pWInfo;

  /* Jump here if malloc fails */
120057
120058
120059
120060
120061
120062
120063
120064
120065
120066
120067
120068
120069
120070
120071
    pOut->zEnd = &pPostOp->z[pPostOp->n];
  }                           

  /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
  ** unary TK_ISNULL or TK_NOTNULL expression. */
  static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
    sqlite3 *db = pParse->db;
    if( db->mallocFailed==0 && pY->op==TK_NULL ){
      pA->op = (u8)op;
      sqlite3ExprDelete(db, pA->pRight);
      pA->pRight = 0;
    }
  }

  /* Construct an expression node for a unary prefix operator







|







121413
121414
121415
121416
121417
121418
121419
121420
121421
121422
121423
121424
121425
121426
121427
    pOut->zEnd = &pPostOp->z[pPostOp->n];
  }                           

  /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
  ** unary TK_ISNULL or TK_NOTNULL expression. */
  static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
    sqlite3 *db = pParse->db;
    if( pY && pA && pY->op==TK_NULL ){
      pA->op = (u8)op;
      sqlite3ExprDelete(db, pA->pRight);
      pA->pRight = 0;
    }
  }

  /* Construct an expression node for a unary prefix operator
122316
122317
122318
122319
122320
122321
122322
122323
122324
122325
122326
122327
122328
122329
122330
122331
122332
  sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328);
}
        break;
      case 111: /* cmd ::= select */
{
  SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
  sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
  sqlite3ExplainBegin(pParse->pVdbe);
  sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy3);
  sqlite3ExplainFinish(pParse->pVdbe);
  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
}
        break;
      case 112: /* select ::= with selectnowith */
{
  Select *p = yymsp[0].minor.yy3, *pNext, *pLoop;
  if( p ){







<
<
<







123672
123673
123674
123675
123676
123677
123678



123679
123680
123681
123682
123683
123684
123685
  sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328);
}
        break;
      case 111: /* cmd ::= select */
{
  SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
  sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);



  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
}
        break;
      case 112: /* select ::= with selectnowith */
{
  Select *p = yymsp[0].minor.yy3, *pNext, *pLoop;
  if( p ){
122375
122376
122377
122378
122379
122380
122381
























122382
122383
122384
122385
122386
122387
122388
        break;
      case 116: /* multiselect_op ::= UNION ALL */
{yygotominor.yy328 = TK_ALL;}
        break;
      case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
  yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
























}
        break;
      case 120: /* values ::= VALUES LP nexprlist RP */
{
  yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
}
        break;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







123728
123729
123730
123731
123732
123733
123734
123735
123736
123737
123738
123739
123740
123741
123742
123743
123744
123745
123746
123747
123748
123749
123750
123751
123752
123753
123754
123755
123756
123757
123758
123759
123760
123761
123762
123763
123764
123765
        break;
      case 116: /* multiselect_op ::= UNION ALL */
{yygotominor.yy328 = TK_ALL;}
        break;
      case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
  yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
#if SELECTTRACE_ENABLED
  /* Populate the Select.zSelName[] string that is used to help with
  ** query planner debugging, to differentiate between multiple Select
  ** objects in a complex query.
  **
  ** If the SELECT keyword is immediately followed by a C-style comment
  ** then extract the first few alphanumeric characters from within that
  ** comment to be the zSelName value.  Otherwise, the label is #N where
  ** is an integer that is incremented with each SELECT statement seen.
  */
  if( yygotominor.yy3!=0 ){
    const char *z = yymsp[-8].minor.yy0.z+6;
    int i;
    sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "#%d",
                     ++pParse->nSelect);
    while( z[0]==' ' ) z++;
    if( z[0]=='/' && z[1]=='*' ){
      z += 2;
      while( z[0]==' ' ) z++;
      for(i=0; sqlite3Isalnum(z[i]); i++){}
      sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "%.*s", i, z);
    }
  }
#endif /* SELECTRACE_ENABLED */
}
        break;
      case 120: /* values ::= VALUES LP nexprlist RP */
{
  yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
}
        break;
123866
123867
123868
123869
123870
123871
123872

123873
123874
123875
123876
123877
123878
123879
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Cx */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Dx */
    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Ex */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,  /* Fx */
};
#define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
#endif



/*
** Return the length of the token that begins at z[0]. 
** Store the token type in *tokenType before returning.
*/
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){







>







125243
125244
125245
125246
125247
125248
125249
125250
125251
125252
125253
125254
125255
125256
125257
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Cx */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Dx */
    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Ex */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,  /* Fx */
};
#define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
#endif
SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }


/*
** Return the length of the token that begins at z[0]. 
** Store the token type in *tokenType before returning.
*/
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
124391
124392
124393
124394
124395
124396
124397







124398
124399
124400
124401
124402
124403
124404
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
** to recognize the end of a trigger can be omitted.  All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
SQLITE_API int sqlite3_complete(const char *zSql){
  u8 state = 0;   /* Current state, using numbers defined in header comment */
  u8 token;       /* Value of the next token */








#ifndef SQLITE_OMIT_TRIGGER
  /* A complex statement machine used to detect the end of a CREATE TRIGGER
  ** statement.  This is the normal case.
  */
  static const u8 trans[8][8] = {
                     /* Token:                                                */







>
>
>
>
>
>
>







125769
125770
125771
125772
125773
125774
125775
125776
125777
125778
125779
125780
125781
125782
125783
125784
125785
125786
125787
125788
125789
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
** to recognize the end of a trigger can be omitted.  All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
SQLITE_API int sqlite3_complete(const char *zSql){
  u8 state = 0;   /* Current state, using numbers defined in header comment */
  u8 token;       /* Value of the next token */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( zSql==0 ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif

#ifndef SQLITE_OMIT_TRIGGER
  /* A complex statement machine used to detect the end of a CREATE TRIGGER
  ** statement.  This is the normal case.
  */
  static const u8 trans[8][8] = {
                     /* Token:                                                */
124989
124990
124991
124992
124993
124994
124995
124996
124997
124998
124999
125000
125001
125002
125003
125004


125005
125006
125007
125008
125009
125010
125011


125012
125013
125014
125015
125016
125017


125018
125019
125020
125021
125022


125023
125024
125025
125026
125027
125028
125029
125030
125031




125032
125033
125034
125035
125036



125037
125038
125039
125040
125041
125042


125043
125044
125045
125046
125047


125048

125049
125050
125051
125052
125053
125054


125055
125056
125057
125058
125059











125060
125061
125062
125063
125064
125065
125066
125067
125068
125069
125070
125071
125072



125073
125074
125075
125076
125077




125078
125079
125080
125081
125082
125083
125084



125085
125086

125087

125088
125089
125090
125091
125092
125093
125094
125095
125096
125097
125098
125099

125100



125101
125102
125103
125104
125105
125106
125107

125108
125109
125110
125111
125112
125113
125114
125115
125116
125117
  ** the SQLite library is in use. */
  if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;

  va_start(ap, op);
  switch( op ){

    /* Mutex configuration options are only available in a threadsafe
    ** compile. 
    */
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
    case SQLITE_CONFIG_SINGLETHREAD: {
      /* Disable all mutexing */
      sqlite3GlobalConfig.bCoreMutex = 0;
      sqlite3GlobalConfig.bFullMutex = 0;
      break;
    }


    case SQLITE_CONFIG_MULTITHREAD: {
      /* Disable mutexing of database connections */
      /* Enable mutexing of core data structures */
      sqlite3GlobalConfig.bCoreMutex = 1;
      sqlite3GlobalConfig.bFullMutex = 0;
      break;
    }


    case SQLITE_CONFIG_SERIALIZED: {
      /* Enable all mutexing */
      sqlite3GlobalConfig.bCoreMutex = 1;
      sqlite3GlobalConfig.bFullMutex = 1;
      break;
    }


    case SQLITE_CONFIG_MUTEX: {
      /* Specify an alternative mutex implementation */
      sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
      break;
    }


    case SQLITE_CONFIG_GETMUTEX: {
      /* Retrieve the current mutex implementation */
      *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;
      break;
    }
#endif


    case SQLITE_CONFIG_MALLOC: {




      /* Specify an alternative malloc implementation */
      sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
      break;
    }
    case SQLITE_CONFIG_GETMALLOC: {



      /* Retrieve the current malloc() implementation */
      if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
      *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m;
      break;
    }
    case SQLITE_CONFIG_MEMSTATUS: {


      /* Enable or disable the malloc status collection */
      sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
      break;
    }
    case SQLITE_CONFIG_SCRATCH: {


      /* Designate a buffer for scratch memory space */

      sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
      sqlite3GlobalConfig.szScratch = va_arg(ap, int);
      sqlite3GlobalConfig.nScratch = va_arg(ap, int);
      break;
    }
    case SQLITE_CONFIG_PAGECACHE: {


      /* Designate a buffer for page cache memory space */
      sqlite3GlobalConfig.pPage = va_arg(ap, void*);
      sqlite3GlobalConfig.szPage = va_arg(ap, int);
      sqlite3GlobalConfig.nPage = va_arg(ap, int);
      break;











    }

    case SQLITE_CONFIG_PCACHE: {
      /* no-op */
      break;
    }
    case SQLITE_CONFIG_GETPCACHE: {
      /* now an error */
      rc = SQLITE_ERROR;
      break;
    }

    case SQLITE_CONFIG_PCACHE2: {



      /* Specify an alternative page cache implementation */
      sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
      break;
    }
    case SQLITE_CONFIG_GETPCACHE2: {




      if( sqlite3GlobalConfig.pcache2.xInit==0 ){
        sqlite3PCacheSetDefault();
      }
      *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2;
      break;
    }




#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
    case SQLITE_CONFIG_HEAP: {

      /* Designate a buffer for heap memory space */

      sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
      sqlite3GlobalConfig.nHeap = va_arg(ap, int);
      sqlite3GlobalConfig.mnReq = va_arg(ap, int);

      if( sqlite3GlobalConfig.mnReq<1 ){
        sqlite3GlobalConfig.mnReq = 1;
      }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){
        /* cap min request size at 2^12 */
        sqlite3GlobalConfig.mnReq = (1<<12);
      }

      if( sqlite3GlobalConfig.pHeap==0 ){

        /* If the heap pointer is NULL, then restore the malloc implementation



        ** back to NULL pointers too.  This will cause the malloc to go
        ** back to its default implementation when sqlite3_initialize() is
        ** run.
        */
        memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
      }else{
        /* The heap pointer is not NULL, then install one of the

        ** mem5.c/mem3.c methods.  The enclosing #if guarantees at
        ** least one of these methods is currently enabled.
        */
#ifdef SQLITE_ENABLE_MEMSYS3
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
#endif
#ifdef SQLITE_ENABLE_MEMSYS5
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5();
#endif
      }







|

|






>
>







>
>






>
>





>
>







<

>
>
>
>
|




>
>
>
|





>
>
|




>
>
|
>






>
>
|




>
>
>
>
>
>
>
>
>
>
>













>
>
>
|




>
>
>
>







>
>
>


>
|
>












>
|
>
>
>
|
|
<



|
>
|
<
<







126374
126375
126376
126377
126378
126379
126380
126381
126382
126383
126384
126385
126386
126387
126388
126389
126390
126391
126392
126393
126394
126395
126396
126397
126398
126399
126400
126401
126402
126403
126404
126405
126406
126407
126408
126409
126410
126411
126412
126413
126414
126415
126416
126417
126418
126419
126420
126421
126422

126423
126424
126425
126426
126427
126428
126429
126430
126431
126432
126433
126434
126435
126436
126437
126438
126439
126440
126441
126442
126443
126444
126445
126446
126447
126448
126449
126450
126451
126452
126453
126454
126455
126456
126457
126458
126459
126460
126461
126462
126463
126464
126465
126466
126467
126468
126469
126470
126471
126472
126473
126474
126475
126476
126477
126478
126479
126480
126481
126482
126483
126484
126485
126486
126487
126488
126489
126490
126491
126492
126493
126494
126495
126496
126497
126498
126499
126500
126501
126502
126503
126504
126505
126506
126507
126508
126509
126510
126511
126512
126513
126514
126515
126516
126517
126518
126519
126520
126521
126522
126523
126524
126525
126526
126527
126528
126529
126530
126531
126532
126533
126534
126535

126536
126537
126538
126539
126540
126541


126542
126543
126544
126545
126546
126547
126548
  ** the SQLite library is in use. */
  if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;

  va_start(ap, op);
  switch( op ){

    /* Mutex configuration options are only available in a threadsafe
    ** compile.
    */
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0  /* IMP: R-54466-46756 */
    case SQLITE_CONFIG_SINGLETHREAD: {
      /* Disable all mutexing */
      sqlite3GlobalConfig.bCoreMutex = 0;
      sqlite3GlobalConfig.bFullMutex = 0;
      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */
    case SQLITE_CONFIG_MULTITHREAD: {
      /* Disable mutexing of database connections */
      /* Enable mutexing of core data structures */
      sqlite3GlobalConfig.bCoreMutex = 1;
      sqlite3GlobalConfig.bFullMutex = 0;
      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */
    case SQLITE_CONFIG_SERIALIZED: {
      /* Enable all mutexing */
      sqlite3GlobalConfig.bCoreMutex = 1;
      sqlite3GlobalConfig.bFullMutex = 1;
      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */
    case SQLITE_CONFIG_MUTEX: {
      /* Specify an alternative mutex implementation */
      sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */
    case SQLITE_CONFIG_GETMUTEX: {
      /* Retrieve the current mutex implementation */
      *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;
      break;
    }
#endif


    case SQLITE_CONFIG_MALLOC: {
      /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a
      ** single argument which is a pointer to an instance of the
      ** sqlite3_mem_methods structure. The argument specifies alternative
      ** low-level memory allocation routines to be used in place of the memory
      ** allocation routines built into SQLite. */
      sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
      break;
    }
    case SQLITE_CONFIG_GETMALLOC: {
      /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a
      ** single argument which is a pointer to an instance of the
      ** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is
      ** filled with the currently defined memory allocation routines. */
      if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
      *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m;
      break;
    }
    case SQLITE_CONFIG_MEMSTATUS: {
      /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes
      ** single argument of type int, interpreted as a boolean, which enables
      ** or disables the collection of memory allocation statistics. */
      sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
      break;
    }
    case SQLITE_CONFIG_SCRATCH: {
      /* EVIDENCE-OF: R-08404-60887 There are three arguments to
      ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from
      ** which the scratch allocations will be drawn, the size of each scratch
      ** allocation (sz), and the maximum number of scratch allocations (N). */
      sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
      sqlite3GlobalConfig.szScratch = va_arg(ap, int);
      sqlite3GlobalConfig.nScratch = va_arg(ap, int);
      break;
    }
    case SQLITE_CONFIG_PAGECACHE: {
      /* EVIDENCE-OF: R-31408-40510 There are three arguments to
      ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory, the size
      ** of each page buffer (sz), and the number of pages (N). */
      sqlite3GlobalConfig.pPage = va_arg(ap, void*);
      sqlite3GlobalConfig.szPage = va_arg(ap, int);
      sqlite3GlobalConfig.nPage = va_arg(ap, int);
      break;
    }
    case SQLITE_CONFIG_PCACHE_HDRSZ: {
      /* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes
      ** a single parameter which is a pointer to an integer and writes into
      ** that integer the number of extra bytes per page required for each page
      ** in SQLITE_CONFIG_PAGECACHE. */
      *va_arg(ap, int*) = 
          sqlite3HeaderSizeBtree() +
          sqlite3HeaderSizePcache() +
          sqlite3HeaderSizePcache1();
      break;
    }

    case SQLITE_CONFIG_PCACHE: {
      /* no-op */
      break;
    }
    case SQLITE_CONFIG_GETPCACHE: {
      /* now an error */
      rc = SQLITE_ERROR;
      break;
    }

    case SQLITE_CONFIG_PCACHE2: {
      /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a
      ** single argument which is a pointer to an sqlite3_pcache_methods2
      ** object. This object specifies the interface to a custom page cache
      ** implementation. */
      sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
      break;
    }
    case SQLITE_CONFIG_GETPCACHE2: {
      /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a
      ** single argument which is a pointer to an sqlite3_pcache_methods2
      ** object. SQLite copies of the current page cache implementation into
      ** that object. */
      if( sqlite3GlobalConfig.pcache2.xInit==0 ){
        sqlite3PCacheSetDefault();
      }
      *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2;
      break;
    }

/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only
** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or
** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
    case SQLITE_CONFIG_HEAP: {
      /* EVIDENCE-OF: R-19854-42126 There are three arguments to
      ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the
      ** number of bytes in the memory buffer, and the minimum allocation size. */
      sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
      sqlite3GlobalConfig.nHeap = va_arg(ap, int);
      sqlite3GlobalConfig.mnReq = va_arg(ap, int);

      if( sqlite3GlobalConfig.mnReq<1 ){
        sqlite3GlobalConfig.mnReq = 1;
      }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){
        /* cap min request size at 2^12 */
        sqlite3GlobalConfig.mnReq = (1<<12);
      }

      if( sqlite3GlobalConfig.pHeap==0 ){
        /* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer)
        ** is NULL, then SQLite reverts to using its default memory allocator
        ** (the system malloc() implementation), undoing any prior invocation of
        ** SQLITE_CONFIG_MALLOC.
        **
        ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to
        ** revert to its default implementation when sqlite3_initialize() is run

        */
        memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
      }else{
        /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the
        ** alternative memory allocator is engaged to handle all of SQLites
        ** memory allocation needs. */


#ifdef SQLITE_ENABLE_MEMSYS3
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
#endif
#ifdef SQLITE_ENABLE_MEMSYS5
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5();
#endif
      }
125136
125137
125138
125139
125140
125141
125142





125143




125144
125145
125146
125147
125148




125149
125150
125151
125152
125153
125154
125155
125156
125157
125158
125159
125160
125161
125162




125163
125164








125165
125166
125167
125168
125169
125170

125171
125172
125173
125174
125175
125176



125177
125178
125179
125180
125181
125182
125183
      */
      typedef void(*LOGFUNC_t)(void*,int,const char*);
      sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
      sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
      break;
    }






    case SQLITE_CONFIG_URI: {




      sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
      break;
    }

    case SQLITE_CONFIG_COVERING_INDEX_SCAN: {




      sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
      break;
    }

#ifdef SQLITE_ENABLE_SQLLOG
    case SQLITE_CONFIG_SQLLOG: {
      typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
      sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
      sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
      break;
    }
#endif

    case SQLITE_CONFIG_MMAP_SIZE: {




      sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64);
      sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);








      if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){
        mxMmap = SQLITE_MAX_MMAP_SIZE;
      }
      sqlite3GlobalConfig.mxMmap = mxMmap;
      if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
      if( szMmap>mxMmap) szMmap = mxMmap;

      sqlite3GlobalConfig.szMmap = szMmap;
      break;
    }

#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC)
    case SQLITE_CONFIG_WIN32_HEAPSIZE: {



      sqlite3GlobalConfig.nHeap = va_arg(ap, int);
      break;
    }
#endif

    default: {
      rc = SQLITE_ERROR;







>
>
>
>
>

>
>
>
>





>
>
>
>














>
>
>
>


>
>
>
>
>
>
>
>
|
<
<
<


>




|

>
>
>







126567
126568
126569
126570
126571
126572
126573
126574
126575
126576
126577
126578
126579
126580
126581
126582
126583
126584
126585
126586
126587
126588
126589
126590
126591
126592
126593
126594
126595
126596
126597
126598
126599
126600
126601
126602
126603
126604
126605
126606
126607
126608
126609
126610
126611
126612
126613
126614
126615
126616
126617
126618
126619
126620
126621



126622
126623
126624
126625
126626
126627
126628
126629
126630
126631
126632
126633
126634
126635
126636
126637
126638
126639
126640
      */
      typedef void(*LOGFUNC_t)(void*,int,const char*);
      sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
      sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
      break;
    }

    /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames
    ** can be changed at start-time using the
    ** sqlite3_config(SQLITE_CONFIG_URI,1) or
    ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls.
    */
    case SQLITE_CONFIG_URI: {
      /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single
      ** argument of type int. If non-zero, then URI handling is globally
      ** enabled. If the parameter is zero, then URI handling is globally
      ** disabled. */
      sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
      break;
    }

    case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
      /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN
      ** option takes a single integer argument which is interpreted as a
      ** boolean in order to enable or disable the use of covering indices for
      ** full table scans in the query optimizer. */
      sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
      break;
    }

#ifdef SQLITE_ENABLE_SQLLOG
    case SQLITE_CONFIG_SQLLOG: {
      typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
      sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
      sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
      break;
    }
#endif

    case SQLITE_CONFIG_MMAP_SIZE: {
      /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit
      ** integer (sqlite3_int64) values that are the default mmap size limit
      ** (the default setting for PRAGMA mmap_size) and the maximum allowed
      ** mmap size limit. */
      sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64);
      sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);
      /* EVIDENCE-OF: R-53367-43190 If either argument to this option is
      ** negative, then that argument is changed to its compile-time default.
      **
      ** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be
      ** silently truncated if necessary so that it does not exceed the
      ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE
      ** compile-time option.
      */
      if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ) mxMmap = SQLITE_MAX_MMAP_SIZE;



      if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
      if( szMmap>mxMmap) szMmap = mxMmap;
      sqlite3GlobalConfig.mxMmap = mxMmap;
      sqlite3GlobalConfig.szMmap = szMmap;
      break;
    }

#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */
    case SQLITE_CONFIG_WIN32_HEAPSIZE: {
      /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit
      ** unsigned integer value that specifies the maximum size of the created
      ** heap. */
      sqlite3GlobalConfig.nHeap = va_arg(ap, int);
      break;
    }
#endif

    default: {
      rc = SQLITE_ERROR;
125253
125254
125255
125256
125257
125258
125259






125260
125261
125262
125263
125264
125265
125266
125267
125268




125269
125270
125271
125272
125273
125274
125275
  return SQLITE_OK;
}

/*
** Return the mutex associated with a database connection.
*/
SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){






  return db->mutex;
}

/*
** Free up as much memory as we can from the given database
** connection.
*/
SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
  int i;




  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  for(i=0; i<db->nDb; i++){
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ){
      Pager *pPager = sqlite3BtreePager(pBt);
      sqlite3PagerShrink(pPager);







>
>
>
>
>
>









>
>
>
>







126710
126711
126712
126713
126714
126715
126716
126717
126718
126719
126720
126721
126722
126723
126724
126725
126726
126727
126728
126729
126730
126731
126732
126733
126734
126735
126736
126737
126738
126739
126740
126741
126742
  return SQLITE_OK;
}

/*
** Return the mutex associated with a database connection.
*/
SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  return db->mutex;
}

/*
** Free up as much memory as we can from the given database
** connection.
*/
SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
  int i;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  for(i=0; i<db->nDb; i++){
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ){
      Pager *pPager = sqlite3BtreePager(pBt);
      sqlite3PagerShrink(pPager);
125351
125352
125353
125354
125355
125356
125357



125358
125359
125360
125361
125362
125363
125364




125365
125366
125367
125368
125369
125370
125371
static int binCollFunc(
  void *padFlag,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  int rc, n;
  n = nKey1<nKey2 ? nKey1 : nKey2;



  rc = memcmp(pKey1, pKey2, n);
  if( rc==0 ){
    if( padFlag
     && allSpaces(((char*)pKey1)+n, nKey1-n)
     && allSpaces(((char*)pKey2)+n, nKey2-n)
    ){
      /* Leave rc unchanged at 0 */




    }else{
      rc = nKey1 - nKey2;
    }
  }
  return rc;
}








>
>
>






|
>
>
>
>







126818
126819
126820
126821
126822
126823
126824
126825
126826
126827
126828
126829
126830
126831
126832
126833
126834
126835
126836
126837
126838
126839
126840
126841
126842
126843
126844
126845
static int binCollFunc(
  void *padFlag,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  int rc, n;
  n = nKey1<nKey2 ? nKey1 : nKey2;
  /* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
  ** strings byte by byte using the memcmp() function from the standard C
  ** library. */
  rc = memcmp(pKey1, pKey2, n);
  if( rc==0 ){
    if( padFlag
     && allSpaces(((char*)pKey1)+n, nKey1-n)
     && allSpaces(((char*)pKey2)+n, nKey2-n)
    ){
      /* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
      ** spaces at the end of either string do not change the result. In other
      ** words, strings will compare equal to one another as long as they
      ** differ only in the number of spaces at the end.
      */
    }else{
      rc = nKey1 - nKey2;
    }
  }
  return rc;
}

125392
125393
125394
125395
125396
125397
125398






125399
125400
125401
125402
125403
125404
125405






125406
125407
125408
125409
125410
125411
125412






125413
125414
125415
125416
125417
125418
125419
  return r;
}

/*
** Return the ROWID of the most recent insert
*/
SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){






  return db->lastRowid;
}

/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
SQLITE_API int sqlite3_changes(sqlite3 *db){






  return db->nChange;
}

/*
** Return the number of changes since the database handle was opened.
*/
SQLITE_API int sqlite3_total_changes(sqlite3 *db){






  return db->nTotalChange;
}

/*
** Close all open savepoints. This function only manipulates fields of the
** database handle object, it does not close any savepoints that may be open
** at the b-tree/pager level.







>
>
>
>
>
>







>
>
>
>
>
>







>
>
>
>
>
>







126866
126867
126868
126869
126870
126871
126872
126873
126874
126875
126876
126877
126878
126879
126880
126881
126882
126883
126884
126885
126886
126887
126888
126889
126890
126891
126892
126893
126894
126895
126896
126897
126898
126899
126900
126901
126902
126903
126904
126905
126906
126907
126908
126909
126910
126911
  return r;
}

/*
** Return the ROWID of the most recent insert
*/
SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  return db->lastRowid;
}

/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
SQLITE_API int sqlite3_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  return db->nChange;
}

/*
** Return the number of changes since the database handle was opened.
*/
SQLITE_API int sqlite3_total_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  return db->nTotalChange;
}

/*
** Close all open savepoints. This function only manipulates fields of the
** database handle object, it does not close any savepoints that may be open
** at the b-tree/pager level.
125671
125672
125673
125674
125675
125676
125677
125678
125679
125680

125681
125682
125683
125684

125685
125686
125687
125688
125689
125690
125691
125692
125693
125694

125695
125696
125697
125698
125699
125700
125701
125702
125703
125704
125705
125706
125707
125708
125709
    sqlite3_free(db->lookaside.pStart);
  }
  sqlite3_free(db);
}

/*
** Rollback all database files.  If tripCode is not SQLITE_OK, then
** any open cursors are invalidated ("tripped" - as in "tripping a circuit
** breaker") and made to return tripCode if there are any further
** attempts to use that cursor.

*/
SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
  int i;
  int inTrans = 0;

  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3BeginBenignMalloc();

  /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). 
  ** This is important in case the transaction being rolled back has
  ** modified the database schema. If the b-tree mutexes are not taken
  ** here, then another shared-cache connection might sneak in between
  ** the database rollback and schema reset, which can cause false
  ** corruption reports in some cases.  */
  sqlite3BtreeEnterAll(db);


  for(i=0; i<db->nDb; i++){
    Btree *p = db->aDb[i].pBt;
    if( p ){
      if( sqlite3BtreeIsInTrans(p) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(p, tripCode);
    }
  }
  sqlite3VtabRollback(db);
  sqlite3EndBenignMalloc();

  if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
    sqlite3ExpirePreparedStatements(db);







|

|
>




>










>







|







127163
127164
127165
127166
127167
127168
127169
127170
127171
127172
127173
127174
127175
127176
127177
127178
127179
127180
127181
127182
127183
127184
127185
127186
127187
127188
127189
127190
127191
127192
127193
127194
127195
127196
127197
127198
127199
127200
127201
127202
127203
127204
    sqlite3_free(db->lookaside.pStart);
  }
  sqlite3_free(db);
}

/*
** Rollback all database files.  If tripCode is not SQLITE_OK, then
** any write cursors are invalidated ("tripped" - as in "tripping a circuit
** breaker") and made to return tripCode if there are any further
** attempts to use that cursor.  Read cursors remain open and valid
** but are "saved" in case the table pages are moved around.
*/
SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
  int i;
  int inTrans = 0;
  int schemaChange;
  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3BeginBenignMalloc();

  /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). 
  ** This is important in case the transaction being rolled back has
  ** modified the database schema. If the b-tree mutexes are not taken
  ** here, then another shared-cache connection might sneak in between
  ** the database rollback and schema reset, which can cause false
  ** corruption reports in some cases.  */
  sqlite3BtreeEnterAll(db);
  schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0;

  for(i=0; i<db->nDb; i++){
    Btree *p = db->aDb[i].pBt;
    if( p ){
      if( sqlite3BtreeIsInTrans(p) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(p, tripCode, !schemaChange);
    }
  }
  sqlite3VtabRollback(db);
  sqlite3EndBenignMalloc();

  if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
    sqlite3ExpirePreparedStatements(db);
125951
125952
125953
125954
125955
125956
125957



125958
125959
125960
125961
125962
125963
125964
** given callback function with the given argument.
*/
SQLITE_API int sqlite3_busy_handler(
  sqlite3 *db,
  int (*xBusy)(void*,int),
  void *pArg
){



  sqlite3_mutex_enter(db->mutex);
  db->busyHandler.xFunc = xBusy;
  db->busyHandler.pArg = pArg;
  db->busyHandler.nBusy = 0;
  db->busyTimeout = 0;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;







>
>
>







127446
127447
127448
127449
127450
127451
127452
127453
127454
127455
127456
127457
127458
127459
127460
127461
127462
** given callback function with the given argument.
*/
SQLITE_API int sqlite3_busy_handler(
  sqlite3 *db,
  int (*xBusy)(void*,int),
  void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE;
#endif
  sqlite3_mutex_enter(db->mutex);
  db->busyHandler.xFunc = xBusy;
  db->busyHandler.pArg = pArg;
  db->busyHandler.nBusy = 0;
  db->busyTimeout = 0;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
125972
125973
125974
125975
125976
125977
125978






125979
125980
125981
125982
125983
125984
125985
125986
125987
125988
125989
125990
125991
125992
125993
125994
125995
125996
125997
125998



125999
126000
126001
126002
126003
126004
126005
126006
126007
126008
126009
126010
126011






126012
126013
126014
126015
126016
126017
126018
*/
SQLITE_API void sqlite3_progress_handler(
  sqlite3 *db, 
  int nOps,
  int (*xProgress)(void*), 
  void *pArg
){






  sqlite3_mutex_enter(db->mutex);
  if( nOps>0 ){
    db->xProgress = xProgress;
    db->nProgressOps = (unsigned)nOps;
    db->pProgressArg = pArg;
  }else{
    db->xProgress = 0;
    db->nProgressOps = 0;
    db->pProgressArg = 0;
  }
  sqlite3_mutex_leave(db->mutex);
}
#endif


/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){



  if( ms>0 ){
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
    db->busyTimeout = ms;
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Cause any pending operation to stop at its earliest opportunity.
*/
SQLITE_API void sqlite3_interrupt(sqlite3 *db){






  db->u1.isInterrupted = 1;
}


/*
** This function is exactly the same as sqlite3_create_function(), except
** that it is designed to be called by internal code. The difference is







>
>
>
>
>
>




















>
>
>













>
>
>
>
>
>







127470
127471
127472
127473
127474
127475
127476
127477
127478
127479
127480
127481
127482
127483
127484
127485
127486
127487
127488
127489
127490
127491
127492
127493
127494
127495
127496
127497
127498
127499
127500
127501
127502
127503
127504
127505
127506
127507
127508
127509
127510
127511
127512
127513
127514
127515
127516
127517
127518
127519
127520
127521
127522
127523
127524
127525
127526
127527
127528
127529
127530
127531
*/
SQLITE_API void sqlite3_progress_handler(
  sqlite3 *db, 
  int nOps,
  int (*xProgress)(void*), 
  void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  if( nOps>0 ){
    db->xProgress = xProgress;
    db->nProgressOps = (unsigned)nOps;
    db->pProgressArg = pArg;
  }else{
    db->xProgress = 0;
    db->nProgressOps = 0;
    db->pProgressArg = 0;
  }
  sqlite3_mutex_leave(db->mutex);
}
#endif


/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  if( ms>0 ){
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
    db->busyTimeout = ms;
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Cause any pending operation to stop at its earliest opportunity.
*/
SQLITE_API void sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return;
  }
#endif
  db->u1.isInterrupted = 1;
}


/*
** This function is exactly the same as sqlite3_create_function(), except
** that it is designed to be called by internal code. The difference is
126142
126143
126144
126145
126146
126147
126148






126149
126150
126151
126152
126153
126154
126155
  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
  void (*xFinal)(sqlite3_context*),
  void (*xDestroy)(void *)
){
  int rc = SQLITE_ERROR;
  FuncDestructor *pArg = 0;






  sqlite3_mutex_enter(db->mutex);
  if( xDestroy ){
    pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
    if( !pArg ){
      xDestroy(p);
      goto out;
    }







>
>
>
>
>
>







127655
127656
127657
127658
127659
127660
127661
127662
127663
127664
127665
127666
127667
127668
127669
127670
127671
127672
127673
127674
  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
  void (*xFinal)(sqlite3_context*),
  void (*xDestroy)(void *)
){
  int rc = SQLITE_ERROR;
  FuncDestructor *pArg = 0;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    return SQLITE_MISUSE_BKPT;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  if( xDestroy ){
    pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
    if( !pArg ){
      xDestroy(p);
      goto out;
    }
126178
126179
126180
126181
126182
126183
126184




126185
126186
126187
126188
126189
126190
126191
  void *p,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
){
  int rc;
  char *zFunc8;




  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
  sqlite3DbFree(db, zFunc8);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);







>
>
>
>







127697
127698
127699
127700
127701
127702
127703
127704
127705
127706
127707
127708
127709
127710
127711
127712
127713
127714
  void *p,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
){
  int rc;
  char *zFunc8;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
  sqlite3DbFree(db, zFunc8);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
126209
126210
126211
126212
126213
126214
126215






126216
126217
126218
126219
126220
126221
126222
SQLITE_API int sqlite3_overload_function(
  sqlite3 *db,
  const char *zName,
  int nArg
){
  int nName = sqlite3Strlen30(zName);
  int rc = SQLITE_OK;






  sqlite3_mutex_enter(db->mutex);
  if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
    rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
                           0, sqlite3InvalidFunction, 0, 0, 0);
  }
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);







>
>
>
>
>
>







127732
127733
127734
127735
127736
127737
127738
127739
127740
127741
127742
127743
127744
127745
127746
127747
127748
127749
127750
127751
SQLITE_API int sqlite3_overload_function(
  sqlite3 *db,
  const char *zName,
  int nArg
){
  int nName = sqlite3Strlen30(zName);
  int rc = SQLITE_OK;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
    return SQLITE_MISUSE_BKPT;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
    rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
                           0, sqlite3InvalidFunction, 0, 0, 0);
  }
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
126230
126231
126232
126233
126234
126235
126236







126237
126238
126239
126240
126241
126242
126243
**
** A NULL trace function means that no tracing is executes.  A non-NULL
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
  void *pOld;







  sqlite3_mutex_enter(db->mutex);
  pOld = db->pTraceArg;
  db->xTrace = xTrace;
  db->pTraceArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pOld;
}







>
>
>
>
>
>
>







127759
127760
127761
127762
127763
127764
127765
127766
127767
127768
127769
127770
127771
127772
127773
127774
127775
127776
127777
127778
127779
**
** A NULL trace function means that no tracing is executes.  A non-NULL
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
  void *pOld;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pOld = db->pTraceArg;
  db->xTrace = xTrace;
  db->pTraceArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pOld;
}
126251
126252
126253
126254
126255
126256
126257







126258
126259
126260
126261
126262
126263
126264
126265
126266
126267
126268
126269
126270
126271
126272
126273
126274
126275
126276
126277







126278
126279
126280
126281
126282
126283
126284
126285
126286
126287
126288
126289
126290
126291
126292
126293
126294
126295







126296
126297
126298
126299
126300
126301
126302
126303
126304
126305
126306
126307
126308
126309
126310
126311
126312
126313







126314
126315
126316
126317
126318
126319
126320
*/
SQLITE_API void *sqlite3_profile(
  sqlite3 *db,
  void (*xProfile)(void*,const char*,sqlite_uint64),
  void *pArg
){
  void *pOld;







  sqlite3_mutex_enter(db->mutex);
  pOld = db->pProfileArg;
  db->xProfile = xProfile;
  db->pProfileArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pOld;
}
#endif /* SQLITE_OMIT_TRACE */

/*
** Register a function to be invoked when a transaction commits.
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
SQLITE_API void *sqlite3_commit_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  int (*xCallback)(void*),  /* Function to invoke on each commit */
  void *pArg                /* Argument to the function */
){
  void *pOld;







  sqlite3_mutex_enter(db->mutex);
  pOld = db->pCommitArg;
  db->xCommitCallback = xCallback;
  db->pCommitArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pOld;
}

/*
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
SQLITE_API void *sqlite3_update_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
  void *pArg                /* Argument to the function */
){
  void *pRet;







  sqlite3_mutex_enter(db->mutex);
  pRet = db->pUpdateArg;
  db->xUpdateCallback = xCallback;
  db->pUpdateArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
}

/*
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
SQLITE_API void *sqlite3_rollback_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  void (*xCallback)(void*), /* Callback function */
  void *pArg                /* Argument to the function */
){
  void *pRet;







  sqlite3_mutex_enter(db->mutex);
  pRet = db->pRollbackArg;
  db->xRollbackCallback = xCallback;
  db->pRollbackArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
}







>
>
>
>
>
>
>




















>
>
>
>
>
>
>


















>
>
>
>
>
>
>


















>
>
>
>
>
>
>







127787
127788
127789
127790
127791
127792
127793
127794
127795
127796
127797
127798
127799
127800
127801
127802
127803
127804
127805
127806
127807
127808
127809
127810
127811
127812
127813
127814
127815
127816
127817
127818
127819
127820
127821
127822
127823
127824
127825
127826
127827
127828
127829
127830
127831
127832
127833
127834
127835
127836
127837
127838
127839
127840
127841
127842
127843
127844
127845
127846
127847
127848
127849
127850
127851
127852
127853
127854
127855
127856
127857
127858
127859
127860
127861
127862
127863
127864
127865
127866
127867
127868
127869
127870
127871
127872
127873
127874
127875
127876
127877
127878
127879
127880
127881
127882
127883
127884
*/
SQLITE_API void *sqlite3_profile(
  sqlite3 *db,
  void (*xProfile)(void*,const char*,sqlite_uint64),
  void *pArg
){
  void *pOld;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pOld = db->pProfileArg;
  db->xProfile = xProfile;
  db->pProfileArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pOld;
}
#endif /* SQLITE_OMIT_TRACE */

/*
** Register a function to be invoked when a transaction commits.
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
SQLITE_API void *sqlite3_commit_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  int (*xCallback)(void*),  /* Function to invoke on each commit */
  void *pArg                /* Argument to the function */
){
  void *pOld;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pOld = db->pCommitArg;
  db->xCommitCallback = xCallback;
  db->pCommitArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pOld;
}

/*
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
SQLITE_API void *sqlite3_update_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
  void *pArg                /* Argument to the function */
){
  void *pRet;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pRet = db->pUpdateArg;
  db->xUpdateCallback = xCallback;
  db->pUpdateArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
}

/*
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
SQLITE_API void *sqlite3_rollback_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  void (*xCallback)(void*), /* Callback function */
  void *pArg                /* Argument to the function */
){
  void *pRet;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pRet = db->pRollbackArg;
  db->xRollbackCallback = xCallback;
  db->pRollbackArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
}
126353
126354
126355
126356
126357
126358
126359



126360
126361
126362
126363
126364
126365
126366
126367
126368
126369
126370
126371
126372
126373
126374
126375
126376
126377
126378
126379






126380
126381
126382
126383
126384
126385
126386
** configured by this function.
*/
SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
#ifdef SQLITE_OMIT_WAL
  UNUSED_PARAMETER(db);
  UNUSED_PARAMETER(nFrame);
#else



  if( nFrame>0 ){
    sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
  }else{
    sqlite3_wal_hook(db, 0, 0);
  }
#endif
  return SQLITE_OK;
}

/*
** Register a callback to be invoked each time a transaction is written
** into the write-ahead-log by this database connection.
*/
SQLITE_API void *sqlite3_wal_hook(
  sqlite3 *db,                    /* Attach the hook to this db handle */
  int(*xCallback)(void *, sqlite3*, const char*, int),
  void *pArg                      /* First argument passed to xCallback() */
){
#ifndef SQLITE_OMIT_WAL
  void *pRet;






  sqlite3_mutex_enter(db->mutex);
  pRet = db->pWalArg;
  db->xWalCallback = xCallback;
  db->pWalArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
#else







>
>
>




















>
>
>
>
>
>







127917
127918
127919
127920
127921
127922
127923
127924
127925
127926
127927
127928
127929
127930
127931
127932
127933
127934
127935
127936
127937
127938
127939
127940
127941
127942
127943
127944
127945
127946
127947
127948
127949
127950
127951
127952
127953
127954
127955
127956
127957
127958
127959
** configured by this function.
*/
SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
#ifdef SQLITE_OMIT_WAL
  UNUSED_PARAMETER(db);
  UNUSED_PARAMETER(nFrame);
#else
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  if( nFrame>0 ){
    sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
  }else{
    sqlite3_wal_hook(db, 0, 0);
  }
#endif
  return SQLITE_OK;
}

/*
** Register a callback to be invoked each time a transaction is written
** into the write-ahead-log by this database connection.
*/
SQLITE_API void *sqlite3_wal_hook(
  sqlite3 *db,                    /* Attach the hook to this db handle */
  int(*xCallback)(void *, sqlite3*, const char*, int),
  void *pArg                      /* First argument passed to xCallback() */
){
#ifndef SQLITE_OMIT_WAL
  void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pRet = db->pWalArg;
  db->xWalCallback = xCallback;
  db->pWalArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
#else
126399
126400
126401
126402
126403
126404
126405




126406
126407
126408
126409
126410
126411
126412
  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
  return SQLITE_OK;
#else
  int rc;                         /* Return code */
  int iDb = SQLITE_MAX_ATTACHED;  /* sqlite3.aDb[] index of db to checkpoint */





  /* Initialize the output variables to -1 in case an error occurs. */
  if( pnLog ) *pnLog = -1;
  if( pnCkpt ) *pnCkpt = -1;

  assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE );
  assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART );







>
>
>
>







127972
127973
127974
127975
127976
127977
127978
127979
127980
127981
127982
127983
127984
127985
127986
127987
127988
127989
  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
  return SQLITE_OK;
#else
  int rc;                         /* Return code */
  int iDb = SQLITE_MAX_ATTACHED;  /* sqlite3.aDb[] index of db to checkpoint */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif

  /* Initialize the output variables to -1 in case an error occurs. */
  if( pnLog ) *pnLog = -1;
  if( pnCkpt ) *pnCkpt = -1;

  assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE );
  assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART );
126796
126797
126798
126799
126800
126801
126802






126803
126804
126805
126806
126807
126808
126809
** A new lower limit does not shrink existing constructs.
** It merely prevents new constructs that exceed the limit
** from forming.
*/
SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
  int oldLimit;








  /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
  ** there is a hard upper bound set at compile-time by a C preprocessor
  ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
  ** "_MAX_".)
  */
  assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );







>
>
>
>
>
>







128373
128374
128375
128376
128377
128378
128379
128380
128381
128382
128383
128384
128385
128386
128387
128388
128389
128390
128391
128392
** A new lower limit does not shrink existing constructs.
** It merely prevents new constructs that exceed the limit
** from forming.
*/
SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
  int oldLimit;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return -1;
  }
#endif

  /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
  ** there is a hard upper bound set at compile-time by a C preprocessor
  ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
  ** "_MAX_".)
  */
  assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
126872
126873
126874
126875
126876
126877
126878

126879
126880
126881
126882
126883
126884
126885
126886
126887
  const char *zVfs = zDefaultVfs;
  char *zFile;
  char c;
  int nUri = sqlite3Strlen30(zUri);

  assert( *pzErrMsg==0 );


  if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) 
   && nUri>=5 && memcmp(zUri, "file:", 5)==0 
  ){
    char *zOpt;
    int eState;                   /* Parser state when parsing URI */
    int iIn;                      /* Input character index */
    int iOut = 0;                 /* Output character index */
    int nByte = nUri+2;           /* Bytes of space to allocate */








>
|
|







128455
128456
128457
128458
128459
128460
128461
128462
128463
128464
128465
128466
128467
128468
128469
128470
128471
  const char *zVfs = zDefaultVfs;
  char *zFile;
  char c;
  int nUri = sqlite3Strlen30(zUri);

  assert( *pzErrMsg==0 );

  if( ((flags & SQLITE_OPEN_URI)             /* IMP: R-48725-32206 */
            || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
   && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
  ){
    char *zOpt;
    int eState;                   /* Parser state when parsing URI */
    int iIn;                      /* Input character index */
    int iOut = 0;                 /* Output character index */
    int nByte = nUri+2;           /* Bytes of space to allocate */

127081
127082
127083
127084
127085
127086
127087



127088
127089
127090
127091
127092
127093
127094
){
  sqlite3 *db;                    /* Store allocated handle here */
  int rc;                         /* Return code */
  int isThreadsafe;               /* True for threadsafe connections */
  char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */
  char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */




  *ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
  if( rc ) return rc;
#endif

  /* Only allow sensible combinations of bits in the flags argument.  







>
>
>







128665
128666
128667
128668
128669
128670
128671
128672
128673
128674
128675
128676
128677
128678
128679
128680
128681
){
  sqlite3 *db;                    /* Store allocated handle here */
  int rc;                         /* Return code */
  int isThreadsafe;               /* True for threadsafe connections */
  char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */
  char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
  if( rc ) return rc;
#endif

  /* Only allow sensible combinations of bits in the flags argument.  
127103
127104
127105
127106
127107
127108
127109
127110


127111
127112
127113
127114
127115
127116
127117
  */
  assert( SQLITE_OPEN_READONLY  == 0x01 );
  assert( SQLITE_OPEN_READWRITE == 0x02 );
  assert( SQLITE_OPEN_CREATE    == 0x04 );
  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
  if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT;



  if( sqlite3GlobalConfig.bCoreMutex==0 ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_NOMUTEX ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_FULLMUTEX ){
    isThreadsafe = 1;







|
>
>







128690
128691
128692
128693
128694
128695
128696
128697
128698
128699
128700
128701
128702
128703
128704
128705
128706
  */
  assert( SQLITE_OPEN_READONLY  == 0x01 );
  assert( SQLITE_OPEN_READWRITE == 0x02 );
  assert( SQLITE_OPEN_CREATE    == 0x04 );
  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
  if( ((1<<(flags&7)) & 0x46)==0 ){
    return SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */
  }

  if( sqlite3GlobalConfig.bCoreMutex==0 ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_NOMUTEX ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_FULLMUTEX ){
    isThreadsafe = 1;
127193
127194
127195
127196
127197
127198
127199



127200
127201
127202
127203

127204
127205
127206
127207



127208
127209
127210
127211
127212
127213
127214
127215
127216
127217
127218
127219
127220
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.



  */
  createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);

  createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
  if( db->mallocFailed ){
    goto opendb_out;
  }



  db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
  assert( db->pDfltColl!=0 );

  /* Also add a UTF-8 case-insensitive collation sequence. */
  createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);

  /* Parse the filename/URI argument. */
  db->openFlags = flags;
  rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
    sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
    sqlite3_free(zErrMsg);







>
>
>




>




>
>
>



<
<
<







128782
128783
128784
128785
128786
128787
128788
128789
128790
128791
128792
128793
128794
128795
128796
128797
128798
128799
128800
128801
128802
128803
128804
128805
128806



128807
128808
128809
128810
128811
128812
128813
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  **
  ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
  ** functions:
  */
  createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
  createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
  createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
  if( db->mallocFailed ){
    goto opendb_out;
  }
  /* EVIDENCE-OF: R-08308-17224 The default collating function for all
  ** strings is BINARY. 
  */
  db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
  assert( db->pDfltColl!=0 );




  /* Parse the filename/URI argument. */
  db->openFlags = flags;
  rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
    sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
    sqlite3_free(zErrMsg);
127368
127369
127370
127371
127372
127373
127374
127375
127376

127377
127378
127379
127380
127381

127382
127383
127384
127385
127386
127387
127388
  const void *zFilename, 
  sqlite3 **ppDb
){
  char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  sqlite3_value *pVal;
  int rc;

  assert( zFilename );
  assert( ppDb );

  *ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
  if( rc ) return rc;
#endif

  pVal = sqlite3ValueNew(0);
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb,
                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
    assert( *ppDb || rc==SQLITE_NOMEM );







|
|
>





>







128961
128962
128963
128964
128965
128966
128967
128968
128969
128970
128971
128972
128973
128974
128975
128976
128977
128978
128979
128980
128981
128982
128983
  const void *zFilename, 
  sqlite3 **ppDb
){
  char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  sqlite3_value *pVal;
  int rc;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
  if( rc ) return rc;
#endif
  if( zFilename==0 ) zFilename = "\000\000";
  pVal = sqlite3ValueNew(0);
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb,
                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
    assert( *ppDb || rc==SQLITE_NOMEM );
127404
127405
127406
127407
127408
127409
127410
127411
127412
127413
127414
127415
127416
127417
127418
127419
127420
127421
127422
127423
127424
127425
127426
127427
127428
127429
127430
127431




127432
127433
127434
127435
127436
127437
127438
SQLITE_API int sqlite3_create_collation(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  int rc;
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

/*
** Register a new collation sequence with the database handle db.
*/
SQLITE_API int sqlite3_create_collation_v2(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*),
  void(*xDel)(void*)
){
  int rc;




  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}







<
<
<
|
<
<
<














>
>
>
>







128999
129000
129001
129002
129003
129004
129005



129006



129007
129008
129009
129010
129011
129012
129013
129014
129015
129016
129017
129018
129019
129020
129021
129022
129023
129024
129025
129026
129027
129028
129029
129030
129031
SQLITE_API int sqlite3_create_collation(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){



  return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0);



}

/*
** Register a new collation sequence with the database handle db.
*/
SQLITE_API int sqlite3_create_collation_v2(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*),
  void(*xDel)(void*)
){
  int rc;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}
127446
127447
127448
127449
127450
127451
127452




127453
127454
127455
127456
127457
127458
127459
  const void *zName,
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  int rc = SQLITE_OK;
  char *zName8;




  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
  if( zName8 ){
    rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0);
    sqlite3DbFree(db, zName8);
  }







>
>
>
>







129039
129040
129041
129042
129043
129044
129045
129046
129047
129048
129049
129050
129051
129052
129053
129054
129055
129056
  const void *zName,
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  int rc = SQLITE_OK;
  char *zName8;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
  if( zName8 ){
    rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0);
    sqlite3DbFree(db, zName8);
  }
127468
127469
127470
127471
127472
127473
127474



127475
127476
127477
127478
127479
127480
127481
127482
127483
127484
127485
127486
127487
127488
127489
127490
127491
127492



127493
127494
127495
127496
127497
127498
127499
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int sqlite3_collation_needed(
  sqlite3 *db, 
  void *pCollNeededArg, 
  void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
){



  sqlite3_mutex_enter(db->mutex);
  db->xCollNeeded = xCollNeeded;
  db->xCollNeeded16 = 0;
  db->pCollNeededArg = pCollNeededArg;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int sqlite3_collation_needed16(
  sqlite3 *db, 
  void *pCollNeededArg, 
  void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
){



  sqlite3_mutex_enter(db->mutex);
  db->xCollNeeded = 0;
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}







>
>
>


















>
>
>







129065
129066
129067
129068
129069
129070
129071
129072
129073
129074
129075
129076
129077
129078
129079
129080
129081
129082
129083
129084
129085
129086
129087
129088
129089
129090
129091
129092
129093
129094
129095
129096
129097
129098
129099
129100
129101
129102
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int sqlite3_collation_needed(
  sqlite3 *db, 
  void *pCollNeededArg, 
  void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  db->xCollNeeded = xCollNeeded;
  db->xCollNeeded16 = 0;
  db->pCollNeededArg = pCollNeededArg;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int sqlite3_collation_needed16(
  sqlite3 *db, 
  void *pCollNeededArg, 
  void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  db->xCollNeeded = 0;
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}
127512
127513
127514
127515
127516
127517
127518






127519
127520
127521
127522
127523
127524
127525
/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
*/
SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){






  return db->autoCommit;
}

/*
** The following routines are substitutes for constants SQLITE_CORRUPT,
** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
** constants.  They serve two purposes:







>
>
>
>
>
>







129115
129116
129117
129118
129119
129120
129121
129122
129123
129124
129125
129126
129127
129128
129129
129130
129131
129132
129133
129134
/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
*/
SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  return db->autoCommit;
}

/*
** The following routines are substitutes for constants SQLITE_CORRUPT,
** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
** constants.  They serve two purposes:
127694
127695
127696
127697
127698
127699
127700



127701
127702
127703
127704
127705
127706
127707
127708
127709
127710
127711
127712
127713



127714
127715
127716
127717
127718
127719
127720
  return rc;
}

/*
** Enable or disable the extended result codes.
*/
SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){



  sqlite3_mutex_enter(db->mutex);
  db->errMask = onoff ? 0xffffffff : 0xff;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

/*
** Invoke the xFileControl method on a particular database.
*/
SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
  int rc = SQLITE_ERROR;
  Btree *pBtree;




  sqlite3_mutex_enter(db->mutex);
  pBtree = sqlite3DbNameToBtree(db, zDbName);
  if( pBtree ){
    Pager *pPager;
    sqlite3_file *fd;
    sqlite3BtreeEnter(pBtree);
    pPager = sqlite3BtreePager(pBtree);







>
>
>













>
>
>







129303
129304
129305
129306
129307
129308
129309
129310
129311
129312
129313
129314
129315
129316
129317
129318
129319
129320
129321
129322
129323
129324
129325
129326
129327
129328
129329
129330
129331
129332
129333
129334
129335
  return rc;
}

/*
** Enable or disable the extended result codes.
*/
SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  db->errMask = onoff ? 0xffffffff : 0xff;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

/*
** Invoke the xFileControl method on a particular database.
*/
SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
  int rc = SQLITE_ERROR;
  Btree *pBtree;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  pBtree = sqlite3DbNameToBtree(db, zDbName);
  if( pBtree ){
    Pager *pPager;
    sqlite3_file *fd;
    sqlite3BtreeEnter(pBtree);
    pPager = sqlite3BtreePager(pBtree);
127987
127988
127989
127990
127991
127992
127993
127994
127995
127996
127997
127998
127999
128000
128001
128002
128003
128004
128005
128006
128007
128008
128009
128010
128011
128012
128013
128014
128015
128016
    ** undo this setting.
    */
    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
      break;
    }

#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
    /*   sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
    **                        sqlite3_stmt*,const char**);
    **
    ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds
    ** a string that describes the optimized parse tree.  This test-control
    ** returns a pointer to that string.
    */
    case SQLITE_TESTCTRL_EXPLAIN_STMT: {
      sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*);
      const char **pzRet = va_arg(ap, const char**);
      *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt);
      break;
    }
#endif

    /*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
    **
    ** Set or clear a flag that indicates that the database file is always well-
    ** formed and never corrupt.  This flag is clear by default, indicating that
    ** database files might have arbitrary corruption.  Setting the flag during
    ** testing causes certain assert() statements in the code to be activated
    ** that demonstrat invariants on well-formed database files.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







129602
129603
129604
129605
129606
129607
129608
















129609
129610
129611
129612
129613
129614
129615
    ** undo this setting.
    */
    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
      break;
    }

















    /*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
    **
    ** Set or clear a flag that indicates that the database file is always well-
    ** formed and never corrupt.  This flag is clear by default, indicating that
    ** database files might have arbitrary corruption.  Setting the flag during
    ** testing causes certain assert() statements in the code to be activated
    ** that demonstrat invariants on well-formed database files.
128065
128066
128067
128068
128069
128070
128071
128072
128073
128074
128075
128076
128077
128078
128079
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation.  The zParam argument is the name of the
** query parameter we seek.  This routine returns the value of the zParam
** parameter if it exists.  If the parameter does not exist, this routine
** returns a NULL pointer.
*/
SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
  if( zFilename==0 ) return 0;
  zFilename += sqlite3Strlen30(zFilename) + 1;
  while( zFilename[0] ){
    int x = strcmp(zFilename, zParam);
    zFilename += sqlite3Strlen30(zFilename) + 1;
    if( x==0 ) return zFilename;
    zFilename += sqlite3Strlen30(zFilename) + 1;
  }







|







129664
129665
129666
129667
129668
129669
129670
129671
129672
129673
129674
129675
129676
129677
129678
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation.  The zParam argument is the name of the
** query parameter we seek.  This routine returns the value of the zParam
** parameter if it exists.  If the parameter does not exist, this routine
** returns a NULL pointer.
*/
SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
  if( zFilename==0 || zParam==0 ) return 0;
  zFilename += sqlite3Strlen30(zFilename) + 1;
  while( zFilename[0] ){
    int x = strcmp(zFilename, zParam);
    zFilename += sqlite3Strlen30(zFilename) + 1;
    if( x==0 ) return zFilename;
    zFilename += sqlite3Strlen30(zFilename) + 1;
  }
128121
128122
128123
128124
128125
128126
128127






128128
128129
128130
128131
128132
128133
128134
128135
128136






128137
128138
128139
128140
128141
128142
128143
}

/*
** Return the filename of the database associated with a database
** connection.
*/
SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){






  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
  return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
}

/*
** Return 1 if database is read-only or 0 if read/write.  Return -1 if
** no such database exists.
*/
SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){






  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
  return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}

/************** End of main.c ************************************************/
/************** Begin file notify.c ******************************************/
/*







>
>
>
>
>
>









>
>
>
>
>
>







129720
129721
129722
129723
129724
129725
129726
129727
129728
129729
129730
129731
129732
129733
129734
129735
129736
129737
129738
129739
129740
129741
129742
129743
129744
129745
129746
129747
129748
129749
129750
129751
129752
129753
129754
}

/*
** Return the filename of the database associated with a database
** connection.
*/
SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
  return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
}

/*
** Return 1 if database is read-only or 0 if read/write.  Return -1 if
** no such database exists.
*/
SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return -1;
  }
#endif
  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
  return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}

/************** End of main.c ************************************************/
/************** Begin file notify.c ******************************************/
/*
132462
132463
132464
132465
132466
132467
132468

132469
132470
132471
132472
132473
132474
132475
  if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++];
  if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++];
  assert( iIdx==nVal );

  /* In case the cursor has been used before, clear it now. */
  sqlite3_finalize(pCsr->pStmt);
  sqlite3_free(pCsr->aDoclist);

  sqlite3Fts3ExprFree(pCsr->pExpr);
  memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));

  /* Set the lower and upper bounds on docids to return */
  pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
  pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64);








>







134073
134074
134075
134076
134077
134078
134079
134080
134081
134082
134083
134084
134085
134086
134087
  if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++];
  if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++];
  assert( iIdx==nVal );

  /* In case the cursor has been used before, clear it now. */
  sqlite3_finalize(pCsr->pStmt);
  sqlite3_free(pCsr->aDoclist);
  sqlite3_free(pCsr->aMatchinfo);
  sqlite3Fts3ExprFree(pCsr->pExpr);
  memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));

  /* Set the lower and upper bounds on docids to return */
  pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
  pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64);

133772
133773
133774
133775
133776
133777
133778
133779
133780
133781
133782
133783
133784
133785
133786
      for(i=0; rc==SQLITE_OK && i<p->nToken && bEof==0; i++){
        rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof);
        if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
          iMax = a[i].iDocid;
          bMaxSet = 1;
        }
      }
      assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
      assert( rc!=SQLITE_OK || bMaxSet );

      /* Keep advancing iterators until they all point to the same document */
      for(i=0; i<p->nToken; i++){
        while( rc==SQLITE_OK && bEof==0 
            && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 
        ){







|







135384
135385
135386
135387
135388
135389
135390
135391
135392
135393
135394
135395
135396
135397
135398
      for(i=0; rc==SQLITE_OK && i<p->nToken && bEof==0; i++){
        rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof);
        if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
          iMax = a[i].iDocid;
          bMaxSet = 1;
        }
      }
      assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
      assert( rc!=SQLITE_OK || bMaxSet );

      /* Keep advancing iterators until they all point to the same document */
      for(i=0; i<p->nToken; i++){
        while( rc==SQLITE_OK && bEof==0 
            && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 
        ){
135889
135890
135891
135892
135893
135894
135895
135896
135897
135898
135899
135900
135901
135902
135903
  sqlite3_tokenizer_cursor *pCursor;
  Fts3Expr *pRet = 0;
  int i = 0;

  /* Set variable i to the maximum number of bytes of input to tokenize. */
  for(i=0; i<n; i++){
    if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
    if( z[i]=='*' || z[i]=='"' ) break;
  }

  *pnConsumed = i;
  rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
  if( rc==SQLITE_OK ){
    const char *zToken;
    int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;







|







137501
137502
137503
137504
137505
137506
137507
137508
137509
137510
137511
137512
137513
137514
137515
  sqlite3_tokenizer_cursor *pCursor;
  Fts3Expr *pRet = 0;
  int i = 0;

  /* Set variable i to the maximum number of bytes of input to tokenize. */
  for(i=0; i<n; i++){
    if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
    if( z[i]=='"' ) break;
  }

  *pnConsumed = i;
  rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
  if( rc==SQLITE_OK ){
    const char *zToken;
    int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
Changes to src/sqlite3.h.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# define SQLITE_API
#endif


/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental.  New applications
** should not use deprecated interfaces - they are support for backwards
** compatibility only.  Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
** These macros used to resolve to various kinds of compiler magic that
** would generate warning messages when they were used.  But that
** compiler magic ended up generating such a flurry of bug reports
** that we have taken it all out and gone back to using simple







|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# define SQLITE_API
#endif


/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental.  New applications
** should not use deprecated interfaces - they are supported for backwards
** compatibility only.  Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
** These macros used to resolve to various kinds of compiler magic that
** would generate warning messages when they were used.  But that
** compiler magic ended up generating such a flurry of bug reports
** that we have taken it all out and gone back to using simple
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.7"
#define SQLITE_VERSION_NUMBER 3008007
#define SQLITE_SOURCE_ID      "2014-09-20 00:35:05 59e2c9df02d7e988c5ad44c560ead1e5288b12e7"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|
|
|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.8"
#define SQLITE_VERSION_NUMBER 3008008
#define SQLITE_SOURCE_ID      "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
1500
1501
1502
1503
1504
1505
1506
1507
1508

1509
1510
1511
1512
1513
1514
1515
1516

1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552






1553
1554
1555
1556

1557
1558

1559
1560
1561
1562
1563


1564
1565

1566

1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578




1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
** ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** it is not possible to set the Serialized [threading mode] and
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
**
** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure.  The argument specifies

** alternative low-level memory allocation routines to be used in place of
** the memory allocation routines built into SQLite.)^ ^SQLite makes
** its own private copy of the content of the [sqlite3_mem_methods] structure
** before the [sqlite3_config()] call returns.</dd>
**
** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure.  The [sqlite3_mem_methods]

** structure is filled with the currently defined memory allocation routines.)^
** This option can be used to overload the default memory allocation
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^This option takes single argument of type int, interpreted as a 
** boolean, which enables or disables the collection of memory allocation 
** statistics. ^(When memory allocation statistics are disabled, the 
** following SQLite interfaces become non-operational:
**   <ul>
**   <li> [sqlite3_memory_used()]
**   <li> [sqlite3_memory_highwater()]
**   <li> [sqlite3_soft_heap_limit64()]
**   <li> [sqlite3_status()]
**   </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for

** scratch memory.  There are three arguments:  A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).  The sz
** argument must be a multiple of 16.
** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will use no more than two scratch buffers per thread.  So
** N should be set to twice the expected maximum number of threads.
** ^SQLite will never require a scratch buffer that is more than 6
** times the database page size. ^If SQLite needs needs additional

** scratch memory beyond what is provided by this configuration option, then 
** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>






**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** the database page cache with the default page cache implementation.  

** This configuration should not be used if an application-define page
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.

** There are three arguments to this option: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 32768) plus a little extra for each
** page header.  ^The page header size is 20 to 40 bytes depending on


** the host architecture.  ^It is harmless, apart from the wasted memory,
** to make sz a little too large.  The first

** argument should point to an allocation of at least sz*N bytes of memory.

** ^SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache.  ^If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.
** The pointer in the first argument must
** be aligned to an 8-byte boundary or subsequent behavior of SQLite
** will be undefined.</dd>
**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^This option specifies a static memory buffer that SQLite will use
** for all of its dynamic memory allocation needs beyond those provided
** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].




** There are three arguments: An 8-byte aligned pointer to the memory,
** the number of bytes in the memory buffer, and the minimum allocation size.
** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
** allocator is engaged to handle all of SQLites memory allocation needs.
** The first pointer (the memory pointer) must be aligned to an 8-byte
** boundary or subsequent behavior of SQLite will be undefined.
** The minimum allocation size is capped at 2**12. Reasonable values
** for the minimum allocation size are 2**5 through 2**8.</dd>
**
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
** alternative low-level mutex routines to be used in place
** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
** content of the [sqlite3_mutex_methods] structure before the call to
** [sqlite3_config()] returns. ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure.  The
** [sqlite3_mutex_methods]
** structure is filled with the currently defined mutex routines.)^
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.   ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(This option takes two arguments that determine the default
** memory allocation for the lookaside memory allocator on each
** [database connection].  The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.)^  ^(This option sets the
** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** verb to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(This option takes a single argument which is a pointer to
** an [sqlite3_pcache_methods2] object.  This object specifies the interface
** to a custom page cache implementation.)^  ^SQLite makes a copy of the
** object and uses it for page cache memory allocations.</dd>
**
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** [sqlite3_pcache_methods2] object.  SQLite copies of the current
** page cache implementation into that object.)^ </dd>
**
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
** global [error log].
** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
** function with a call signature of void(*)(void*,int,const char*), 







|
|
>






|
|
>






|
|
|













|
>
|


|
<


|
<
|
|
>

|
>
>
>
>
>
>


|
|
>

|
>
|


|
|
>
>
|
|
>
|
>



|
<
<
<


|
|
|
>
>
>
>
|




|
<







|
|
|









|
|











|
|
|

|
|
|



|
|
|
|


|
|







1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549

1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584



1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
** ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** it is not possible to set the Serialized [threading mode] and
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
**
** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
** <dd> ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is 
** a pointer to an instance of the [sqlite3_mem_methods] structure.
** The argument specifies
** alternative low-level memory allocation routines to be used in place of
** the memory allocation routines built into SQLite.)^ ^SQLite makes
** its own private copy of the content of the [sqlite3_mem_methods] structure
** before the [sqlite3_config()] call returns.</dd>
**
** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which
** is a pointer to an instance of the [sqlite3_mem_methods] structure.
** The [sqlite3_mem_methods]
** structure is filled with the currently defined memory allocation routines.)^
** This option can be used to overload the default memory allocation
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
** memory allocation statistics. ^(When memory allocation statistics are disabled, the 
** following SQLite interfaces become non-operational:
**   <ul>
**   <li> [sqlite3_memory_used()]
**   <li> [sqlite3_memory_highwater()]
**   <li> [sqlite3_soft_heap_limit64()]
**   <li> [sqlite3_status()]
**   </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
** that SQLite can use for scratch memory.  ^(There are three arguments
** to SQLITE_CONFIG_SCRATCH:  A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).)^

** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will not use more than one scratch buffers per thread.

** ^SQLite will never request a scratch buffer that is more than 6
** times the database page size.
** ^If SQLite needs needs additional
** scratch memory beyond what is provided by this configuration option, then 
** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
** ^When the application provides any amount of scratch memory using
** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
** [sqlite3_malloc|heap allocations].
** This can help [Robson proof|prevent memory allocation failures] due to heap
** fragmentation in low-memory embedded systems.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
** that SQLite can use for the database page cache with the default page
** cache implementation.  
** This configuration should not be used if an application-define page
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
** configuration option.
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 32768) plus some extra bytes for each
** page header.  ^The number of extra bytes needed by the page header
** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option 
** to [sqlite3_config()].
** ^It is harmless, apart from the wasted memory,
** for the sz parameter to be larger than necessary.  The first
** argument should pointer to an 8-byte aligned block of memory that
** is at least sz*N bytes of memory, otherwise subsequent behavior is
** undefined.
** ^SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache.  ^If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>



**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
** that SQLite will use for all of its dynamic memory allocation needs
** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
** ^There are three arguments to SQLITE_CONFIG_HEAP:
** An 8-byte aligned pointer to the memory,
** the number of bytes in the memory buffer, and the minimum allocation size.
** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
** memory pointer is not NULL then the alternative memory

** allocator is engaged to handle all of SQLites memory allocation needs.
** The first pointer (the memory pointer) must be aligned to an 8-byte
** boundary or subsequent behavior of SQLite will be undefined.
** The minimum allocation size is capped at 2**12. Reasonable values
** for the minimum allocation size are 2**5 through 2**8.</dd>
**
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
** pointer to an instance of the [sqlite3_mutex_methods] structure.
** The argument specifies alternative low-level mutex routines to be used in place
** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
** content of the [sqlite3_mutex_methods] structure before the call to
** [sqlite3_config()] returns. ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which
** is a pointer to an instance of the [sqlite3_mutex_methods] structure.  The
** [sqlite3_mutex_methods]
** structure is filled with the currently defined mutex routines.)^
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.   ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
** the default size of lookaside memory on each [database connection].
** The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.)^  ^(SQLITE_CONFIG_LOOKASIDE
** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** option to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is 
** a pointer to an [sqlite3_pcache_methods2] object.  This object specifies
** the interface to a custom page cache implementation.)^
** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
**
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which
** is a pointer to an [sqlite3_pcache_methods2] object.  SQLite copies of the current
** page cache implementation into that object.)^ </dd>
**
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
** global [error log].
** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
** function with a call signature of void(*)(void*,int,const char*), 
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681
** log message after formatting via [sqlite3_snprintf()].
** The SQLite logging interface is not reentrant; the logger function
** supplied by the application must not invoke any SQLite interface.
** In a multi-threaded application, the application-defined logger
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for

** full table scans in the query optimizer.  ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.







|
|
|
|









|
|
>
|







1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
** log message after formatting via [sqlite3_snprintf()].
** The SQLite logging interface is not reentrant; the logger function
** supplied by the application must not invoke any SQLite interface.
** In a multi-threaded application, the application-defined logger
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int.
** If non-zero, then URI handling is globally enabled. If the parameter is zero,
** then URI handling is globally disabled.)^ ^If URI handling is globally enabled,
** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd>^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer
** argument which is interpreted as a boolean in order to enable or disable
** the use of covering indices for full table scans in the query optimizer.
** ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726









1727
1728
1729
1730
1731
1732
1733
** <dt>SQLITE_CONFIG_MMAP_SIZE
** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
** cannot be changed at run-time.  Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
**
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
** <dd>^This option is only available if SQLite is compiled for Windows
** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
** </dl>









*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */







|
|






|
|
|


>
>
>
>
>
>
>
>
>







1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
** <dt>SQLITE_CONFIG_MMAP_SIZE
** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
** will be silently truncated if necessary so that it does not exceed the
** compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
**
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
** </dl>
**
** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
** is a pointer to an integer and writes into that integer the number of extra
** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of
** extra space required can change depending on the compiler,
** target platform, and SQLite version.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */


/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**







>







1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880



1881
1882
1883
1884
1885
1886
1887



1888
1889
1890
1891
1892
1893


1894

1895
1896
1897
1898
1899
1900
1901
1902
1903

1904
1905

1906
1907
1908




1909
1910
1911
1912

1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933


1934
1935

1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
** last insert [rowid].
*/
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);

/*
** CAPI3REF: Count The Number Of Rows Modified
**
** ^This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
** on the [database connection] specified by the first parameter.



** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
** or [DELETE] statement are counted.  Auxiliary changes caused by
** triggers or [foreign key actions] are not counted.)^ Use the
** [sqlite3_total_changes()] function to find the total number of changes
** including changes caused by triggers and foreign key actions.
**
** ^Changes to a view that are simulated by an [INSTEAD OF trigger]



** are not counted.  Only real table changes are counted.
**
** ^(A "row change" is a change to a single row of a single table
** caused by an INSERT, DELETE, or UPDATE statement.  Rows that
** are changed as side effects of [REPLACE] constraint resolution,
** rollback, ABORT processing, [DROP TABLE], or by any other


** mechanisms do not count as direct row changes.)^

**
** A "trigger context" is a scope of execution that begins and
** ends with the script of a [CREATE TRIGGER | trigger]. 
** Most SQL statements are
** evaluated outside of any trigger.  This is the "top level"
** trigger context.  If a trigger fires from the top level, a
** new trigger context is entered for the duration of that one
** trigger.  Subtriggers create subcontexts for their duration.
**

** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
** not create a new trigger context.

**
** ^This function returns the number of direct row changes in the
** most recent INSERT, UPDATE, or DELETE statement within the same




** trigger context.
**
** ^Thus, when called from the top level, this function returns the
** number of changes in the most recent INSERT, UPDATE, or DELETE

** that also occurred at the top level.  ^(Within the body of a trigger,
** the sqlite3_changes() interface can be called to find the number of
** changes in the most recently completed INSERT, UPDATE, or DELETE
** statement within the body of the same trigger.
** However, the number returned does not include changes
** caused by subtriggers since those have their own context.)^
**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_changes(sqlite3*);

/*
** CAPI3REF: Total Number Of Rows Modified
**
** ^This function returns the number of row changes caused by [INSERT],
** [UPDATE] or [DELETE] statements since the [database connection] was opened.


** ^(The count returned by sqlite3_total_changes() includes all changes
** from all [CREATE TRIGGER | trigger] contexts and changes made by

** [foreign key actions]. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing.  The
** count does not include rows of views that fire an [INSTEAD OF trigger],
** though if the INSTEAD OF trigger makes changes of its own, those changes 
** are counted.)^
** ^The sqlite3_total_changes() function counts the changes as soon as
** the statement that makes them is completed (when the statement handle
** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
**
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/







|
|
|
>
>
>
|
|
|
<
<
|
|
>
>
>
|

<
<
<
<
>
>
|
>
|
<
<
<
<
<
<
<
|
>
|
<
>
|
<
|
>
>
>
>
|
|
|
|
>
|
|
<
|
<
<













|
|
>
>
|
<
>
|
<
<
|
|
|
<
<
<
|







1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911


1912
1913
1914
1915
1916
1917
1918




1919
1920
1921
1922
1923







1924
1925
1926

1927
1928

1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940

1941


1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959

1960
1961


1962
1963
1964



1965
1966
1967
1968
1969
1970
1971
1972
** last insert [rowid].
*/
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);

/*
** CAPI3REF: Count The Number Of Rows Modified
**
** ^This function returns the number of rows modified, inserted or
** deleted by the most recently completed INSERT, UPDATE or DELETE
** statement on the database connection specified by the only parameter.
** ^Executing any other type of SQL statement does not modify the value
** returned by this function.
**
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], 
** [foreign key actions] or [REPLACE] constraint resolution are not counted.


** 
** Changes to a view that are intercepted by 
** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value 
** returned by sqlite3_changes() immediately after an INSERT, UPDATE or 
** DELETE statement run on a view is always zero. Only changes made to real 
** tables are counted.
**




** Things are more complicated if the sqlite3_changes() function is
** executed while a trigger program is running. This may happen if the
** program uses the [changes() SQL function], or if some other callback
** function invokes sqlite3_changes() directly. Essentially:
** 







** <ul>
**   <li> ^(Before entering a trigger program the value returned by
**        sqlite3_changes() function is saved. After the trigger program 

**        has finished, the original value is restored.)^
** 

**   <li> ^(Within a trigger program each INSERT, UPDATE and DELETE 
**        statement sets the value returned by sqlite3_changes() 
**        upon completion as normal. Of course, this value will not include 
**        any changes performed by sub-triggers, as the sqlite3_changes() 
**        value will be saved and restored after each sub-trigger has run.)^
** </ul>
** 
** ^This means that if the changes() SQL function (or similar) is used
** by the first INSERT, UPDATE or DELETE statement within a trigger, it 
** returns the value as set when the calling statement began executing.
** ^If it is used by the second or subsequent such statement within a trigger 
** program, the value returned reflects the number of rows modified by the 

** previous INSERT, UPDATE or DELETE statement within the same trigger.


**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_changes(sqlite3*);

/*
** CAPI3REF: Total Number Of Rows Modified
**
** ^This function returns the total number of rows inserted, modified or
** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
** since the database connection was opened, including those executed as
** part of trigger programs. ^Executing any other type of SQL statement
** does not affect the value returned by sqlite3_total_changes().

** 
** ^Changes made as part of [foreign key actions] are included in the


** count, but those made as part of REPLACE constraint resolution are
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
** are not counted.



** 
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426

2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random [ROWID | ROWIDs] when inserting new records into a table that
** already uses the largest possible [ROWID].  The PRNG is also used for
** the build-in random() and randomblob() SQL functions.  This interface allows
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
** ^If N is less than one, then P can be a NULL pointer.
**
** ^If this routine has not been previously called or if the previous
** call had N less than one, then the PRNG is seeded using randomness

** obtained from the xRandomness method of the default [sqlite3_vfs] object.
** ^If the previous call to this routine had an N of 1 or more then
** the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
SQLITE_API void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks







|


|
>
|
|
|







2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random [ROWID | ROWIDs] when inserting new records into a table that
** already uses the largest possible [ROWID].  The PRNG is also used for
** the build-in random() and randomblob() SQL functions.  This interface allows
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
** ^The P parameter can be a NULL pointer.
**
** ^If this routine has not been previously called or if the previous
** call had N less than one or a NULL pointer for P, then the PRNG is
** seeded using randomness obtained from the xRandomness method of
** the default [sqlite3_vfs] object.
** ^If the previous call to this routine had an N of 1 or more and a
** non-NULL P then the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
SQLITE_API void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
** object.)^ ^(If the database is opened (and/or created) successfully, then
** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.)^ ^The
** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
** an English language description of the error following a failure of any
** of the sqlite3_open() routines.
**
** ^The default encoding for the database will be UTF-8 if
** sqlite3_open() or sqlite3_open_v2() is called and
** UTF-16 in the native byte order if sqlite3_open16() is used.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
** passing it to [sqlite3_close()] when it is no longer required.
**
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control







|
|
|







2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
** object.)^ ^(If the database is opened (and/or created) successfully, then
** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.)^ ^The
** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
** an English language description of the error following a failure of any
** of the sqlite3_open() routines.
**
** ^The default encoding will be UTF-8 for databases created using
** sqlite3_open() or sqlite3_open_v2().  ^The default encoding for databases
** created using sqlite3_open16() will be UTF-16 in the native byte order.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
** passing it to [sqlite3_close()] when it is no longer required.
**
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767

2768
2769
2770
2771
2772
2773
2774
2775
** present, is ignored.
**
** ^SQLite uses the path component of the URI as the name of the disk file
** which contains the database. ^If the path begins with a '/' character, 
** then it is interpreted as an absolute path. ^If the path does not begin 
** with a '/' (meaning that the authority section is omitted from the URI)
** then the path is interpreted as a relative path. 
** ^On windows, the first component of an absolute path 
** is a drive specification (e.g. "C:").
**
** [[core URI query parameters]]
** The query component of a URI may contain parameters that are interpreted
** either by SQLite itself, or by a [VFS | custom VFS implementation].

** SQLite interprets the following three query parameters:
**
** <ul>
**   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
**     a VFS object that provides the operating system interface that should
**     be used to access the database file on disk. ^If this option is set to
**     an empty string the default VFS object is used. ^Specifying an unknown
**     VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is







|
|




>
|







2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
** present, is ignored.
**
** ^SQLite uses the path component of the URI as the name of the disk file
** which contains the database. ^If the path begins with a '/' character, 
** then it is interpreted as an absolute path. ^If the path does not begin 
** with a '/' (meaning that the authority section is omitted from the URI)
** then the path is interpreted as a relative path. 
** ^(On windows, the first component of an absolute path 
** is a drive specification (e.g. "C:").)^
**
** [[core URI query parameters]]
** The query component of a URI may contain parameters that are interpreted
** either by SQLite itself, or by a [VFS | custom VFS implementation].
** SQLite and its built-in [VFSes] interpret the
** following query parameters:
**
** <ul>
**   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
**     a VFS object that provides the operating system interface that should
**     be used to access the database file on disk. ^If this option is set to
**     an empty string the default VFS object is used. ^Specifying an unknown
**     VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
**     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
**     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
**     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
**     a URI filename, its value overrides any behavior requested by setting
**     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
**
**  <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
**     "1") or "false" (or "off" or "no" or "0") to indicate that the
**     [powersafe overwrite] property does or does not apply to the
**     storage media on which the database file resides.  ^The psow query
**     parameter only works for the built-in unix and Windows VFSes.
**
**  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
**     which if set disables file locking in rollback journal modes.  This
**     is useful for accessing a database on a filesystem that does not
**     support locking.  Caution:  Database corruption might result if two
**     or more processes write to the same database and any one of those
**     processes uses nolock=1.







|
<

|
<







2818
2819
2820
2821
2822
2823
2824
2825

2826
2827

2828
2829
2830
2831
2832
2833
2834
**     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
**     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
**     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
**     a URI filename, its value overrides any behavior requested by setting
**     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
**
**  <li> <b>psow</b>: ^The psow parameter indicates whether or not the

**     [powersafe overwrite] property does or does not apply to the
**     storage media on which the database file resides.

**
**  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
**     which if set disables file locking in rollback journal modes.  This
**     is useful for accessing a database on a filesystem that does not
**     support locking.  Caution:  Database corruption might result if two
**     or more processes write to the same database and any one of those
**     processes uses nolock=1.
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated.  If any NUL characters occur at byte offsets less than 
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs.  The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it.  ^The destructor is called
** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
** to specify the encoding of the text in the third parameter.  If
** the sixth argument to sqlite3_bind_text64() is not how of the
** allowed values shown above, or if the text encoding is different
** from the encoding specified by the sixth parameter, then the behavior
** is undefined.
**
** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
** (just an integer to hold its size) while it is being processed.







|
|

|
<










|







3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425

3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated.  If any NUL characters occur at byte offsets less than 
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs.  The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to the BLOB and string binding interfaces
** is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it.  ^The destructor is called
** to dispose of the BLOB or string even if the call to bind API fails.

** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
** to specify the encoding of the text in the third parameter.  If
** the sixth argument to sqlite3_bind_text64() is not one of the
** allowed values shown above, or if the text encoding is different
** from the encoding specified by the sixth parameter, then the behavior
** is undefined.
**
** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
** (just an integer to hold its size) while it is being processed.
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162

/*
** CAPI3REF: Text Encodings
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
*/
#define SQLITE_UTF8           1
#define SQLITE_UTF16LE        2
#define SQLITE_UTF16BE        3
#define SQLITE_UTF16          4    /* Use native byte order */
#define SQLITE_ANY            5    /* Deprecated */
#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */

/*
** CAPI3REF: Function Flags
**







|
|
|







4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181

/*
** CAPI3REF: Text Encodings
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
*/
#define SQLITE_UTF8           1    /* IMP: R-37514-35566 */
#define SQLITE_UTF16LE        2    /* IMP: R-03371-37637 */
#define SQLITE_UTF16BE        3    /* IMP: R-51971-34154 */
#define SQLITE_UTF16          4    /* Use native byte order */
#define SQLITE_ANY            5    /* Deprecated */
#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */

/*
** CAPI3REF: Function Flags
**
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
** of the application-defined function to be the 64-bit signed integer
** value given in the 2nd argument.
**
** ^The sqlite3_result_null() interface sets the return value
** of the application-defined function to be NULL.
**
** ^The sqlite3_result_text(), sqlite3_result_text16(),
** sqlite3_result_text16le(), and sqlite3_result_text16be()
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^The sqlite3_result_text64() interface sets the return value of an
** application-defined function to be a text string in an encoding
** specified by the fifth (and last) parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].







|







4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
** of the application-defined function to be the 64-bit signed integer
** value given in the 2nd argument.
**
** ^The sqlite3_result_null() interface sets the return value
** of the application-defined function to be NULL.
**
** ^The sqlite3_result_text(), sqlite3_result_text16(),
** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^The sqlite3_result_text64() interface sets the return value of an
** application-defined function to be a text string in an encoding
** specified by the fifth (and last) parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657




5658
5659





5660















5661
5662
5663
5664
5665

5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
** in other words, the same BLOB that would be selected by:
**
** <pre>
**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**
** ^If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. ^If it is zero, the BLOB is opened for read access.
** ^It is not possible to open a column that is part of an index or primary 
** key for writing. ^If [foreign key constraints] are enabled, it is 
** not possible to open a column that is part of a [child key] for writing.
**
** ^Note that the database name is not the filename that contains
** the database but rather the symbolic name of the database that
** appears after the AS keyword when the database is connected using [ATTACH].
** ^For the main database file, the database name is "main".
** ^For TEMP tables, the database name is "temp".
**




** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set





** to be a null pointer.)^















** ^This function sets the [database connection] error code and message
** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
** functions. ^Note that the *ppBlob variable is always initialized in a
** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
** regardless of the success or failure of this routine.

**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
** ^(Changes written into a BLOB prior to the BLOB expiring are not
** rolled back by the expiration of the BLOB.  Such changes will eventually
** commit if the transaction continues to completion.)^
**
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  ^The size of a blob may not be changed by this
** interface.  Use the [UPDATE] SQL command to change the size of a
** blob.
**
** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
** table.  Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
** this interface.
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
*/
SQLITE_API int sqlite3_blob_open(
  sqlite3*,
  const char *zDb,








<
<
<
<
<
<
|
|
|
|
|

>
>
>
>
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
<
>

















<
<
<

|
|
<







5657
5658
5659
5660
5661
5662
5663
5664






5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699



5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717



5718
5719
5720

5721
5722
5723
5724
5725
5726
5727
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
** in other words, the same BLOB that would be selected by:
**
** <pre>
**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**






** ^(Parameter zDb is not the filename that contains the database, but 
** rather the symbolic name of the database. For attached databases, this is
** the name that appears after the AS keyword in the [ATTACH] statement.
** For the main database file, the database name is "main". For TEMP
** tables, the database name is "temp".)^
**
** ^If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. ^If the flags parameter is zero, the BLOB is opened for
** read-only access.
**
** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
** in *ppBlob. Otherwise an [error code] is returned and, unless the error
** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
** the API is not misused, it is always safe to call [sqlite3_blob_close()] 
** on *ppBlob after this function it returns.
**
** This function fails with SQLITE_ERROR if any of the following are true:
** <ul>
**   <li> ^(Database zDb does not exist)^, 
**   <li> ^(Table zTable does not exist within database zDb)^, 
**   <li> ^(Table zTable is a WITHOUT ROWID table)^, 
**   <li> ^(Column zColumn does not exist)^,
**   <li> ^(Row iRow is not present in the table)^,
**   <li> ^(The specified column of row iRow contains a value that is not
**         a TEXT or BLOB value)^,
**   <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE 
**         constraint and the blob is being opened for read/write access)^,
**   <li> ^([foreign key constraints | Foreign key constraints] are enabled, 
**         column zColumn is part of a [child key] definition and the blob is
**         being opened for read/write access)^.
** </ul>
**
** ^Unless it returns SQLITE_MISUSE, this function sets the 
** [database connection] error code and message accessible via 
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 



**
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
** ^(Changes written into a BLOB prior to the BLOB expiring are not
** rolled back by the expiration of the BLOB.  Such changes will eventually
** commit if the transaction continues to completion.)^
**
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  ^The size of a blob may not be changed by this
** interface.  Use the [UPDATE] SQL command to change the size of a
** blob.
**



** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function may be used to create a 
** zero-filled blob to read or write using the incremental-blob interface.

**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
*/
SQLITE_API int sqlite3_blob_open(
  sqlite3*,
  const char *zDb,
5724
5725
5726
5727
5728
5729
5730
5731


5732


5733

5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748


5749
5750
5751
5752
5753
5754
5755
** ^This function sets the database handle error code and message.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);

/*
** CAPI3REF: Close A BLOB Handle
**
** ^Closes an open [BLOB handle].


**


** ^Closing a BLOB shall cause the current transaction to commit

** if there are no other BLOBs, no pending prepared statements, and the
** database connection is in [autocommit mode].
** ^If any writes were made to the BLOB, they might be held in cache
** until the close operation if they will fit.
**
** ^(Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
** at the time when the BLOB is closed.  Any errors that occur during
** closing are reported as a non-zero return value.)^
**
** ^(The BLOB is closed unconditionally.  Even if this routine returns
** an error code, the BLOB is still closed.)^
**
** ^Calling this routine with a null pointer (such as would be returned
** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.


*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *);

/*
** CAPI3REF: Return The Size Of An Open BLOB
**
** ^Returns the size in bytes of the BLOB accessible via the 







|
>
>

>
>
|
>
|
<
<
<

|
<
<
|
<
<
<
<
|
|
>
>







5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770



5771
5772


5773




5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
** ^This function sets the database handle error code and message.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);

/*
** CAPI3REF: Close A BLOB Handle
**
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
** unconditionally.  Even if this routine returns an error code, the 
** handle is still closed.)^
**
** ^If the blob handle being closed was opened for read-write access, and if
** the database is in auto-commit mode and there are no other open read-write
** blob handles or active write statements, the current transaction is
** committed. ^If an error occurs while committing the transaction, an error
** code is returned and the transaction rolled back.



**
** Calling this function with an argument that is not a NULL pointer or an


** open blob handle results in undefined behaviour. ^Calling this routine 




** with a null pointer (such as would be returned by a failed call to 
** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
** is passed a valid open blob handle, the values returned by the 
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *);

/*
** CAPI3REF: Return The Size Of An Open BLOB
**
** ^Returns the size in bytes of the BLOB accessible via the 
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800






5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812

5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
** See also: [sqlite3_blob_write()].
*/
SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);

/*
** CAPI3REF: Write Data Into A BLOB Incrementally
**
** ^This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. ^N bytes of data are copied from the buffer Z
** into the open BLOB, starting at offset iOffset.






**
** ^If the [BLOB handle] passed as the first argument was not opened for
** writing (the flags parameter to [sqlite3_blob_open()] was zero),
** this function returns [SQLITE_READONLY].
**
** ^This function may only modify the contents of the BLOB; it is
** not possible to increase the size of a BLOB using this API.
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written.  ^If N is
** less than zero [SQLITE_ERROR] is returned and no data is written.
** The size of the BLOB (and hence the maximum value of N+iOffset)
** can be determined using the [sqlite3_blob_bytes()] interface.

**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
** before the [BLOB handle] expired are not rolled back by the
** expiration of the handle, though of course those changes might
** have been overwritten by the statement that expired the BLOB handle
** or by other independent statements.
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an  [error code] or an [extended error code] is returned.)^
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()].  Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
**
** See also: [sqlite3_blob_read()].
*/







|
|
|
>
>
>
>
>
>





|


|
<
|
|
>








<
<
<







5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844

5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855



5856
5857
5858
5859
5860
5861
5862
** See also: [sqlite3_blob_write()].
*/
SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);

/*
** CAPI3REF: Write Data Into A BLOB Incrementally
**
** ^(This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. N bytes of data are copied from the buffer Z
** into the open BLOB, starting at offset iOffset.)^
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an  [error code] or an [extended error code] is returned.)^
** ^Unless SQLITE_MISUSE is returned, this function sets the 
** [database connection] error code and message accessible via 
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
**
** ^If the [BLOB handle] passed as the first argument was not opened for
** writing (the flags parameter to [sqlite3_blob_open()] was zero),
** this function returns [SQLITE_READONLY].
**
** This function may only modify the contents of the BLOB; it is
** not possible to increase the size of a BLOB using this API.
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written. The size of the 

** BLOB (and hence the maximum value of N+iOffset) can be determined 
** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less 
** than zero [SQLITE_ERROR] is returned and no data is written.
**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
** before the [BLOB handle] expired are not rolled back by the
** expiration of the handle, though of course those changes might
** have been overwritten by the statement that expired the BLOB handle
** or by other independent statements.
**



** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()].  Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
**
** See also: [sqlite3_blob_read()].
*/
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915

5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967

5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
** use by SQLite, code that links against SQLite is
** permitted to use any of these routines.
**
** The SQLite source code contains multiple implementations
** of these mutex routines.  An appropriate implementation
** is selected automatically at compile-time.  ^(The following
** implementations are available in the SQLite core:
**
** <ul>
** <li>   SQLITE_MUTEX_PTHREADS
** <li>   SQLITE_MUTEX_W32
** <li>   SQLITE_MUTEX_NOOP
** </ul>)^
**
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
** and Windows.
**
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().)^
**
** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^If it returns NULL
** that means that a mutex could not be allocated.  ^SQLite
** will unwind its stack and return an error.  ^(The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2

** </ul>)^
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
** cause sqlite3_mutex_alloc() to create
** a new mutex.  ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  ^SQLite will only request a recursive mutex in
** cases where it really needs one.  ^If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
** a pointer to a static preexisting mutex.  ^Six static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  ^But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
**
** ^The sqlite3_mutex_free() routine deallocates a previously
** allocated dynamic mutex.  ^SQLite is careful to deallocate every
** dynamic mutex that it allocates.  The dynamic mutexes must not be in
** use when they are deallocated.  Attempting to deallocate a static
** mutex results in undefined behavior.  ^SQLite never deallocates
** a static mutex.
**
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  ^If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
** upon successful entry.  ^(Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
** In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.)^  ^(If the same thread tries to enter any other
** kind of mutex more than once, the behavior is undefined.
** SQLite will never exhibit
** such behavior in its own use of mutexes.)^
**
** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
** will always return SQLITE_BUSY.  The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^

**
** ^The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.   ^(The behavior
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated.  SQLite will
** never do either.)^
**
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
** behave as no-ops.
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);

/*
** CAPI3REF: Mutex Methods Object
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
**
** Usually, the default mutex implementations provided by SQLite are
** sufficient, however the user has the option of substituting a custom
** implementation for specialized deployments or systems for which SQLite
** does not provide a suitable implementation. In this case, the user
** creates and populates an instance of this structure to pass
** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
** Additionally, an instance of this structure can be used as an
** output variable when querying the system for the current mutex
** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
**
** ^The xMutexInit method defined by this structure is invoked as







|






|

|

|



|





|


|
|
|
|












>
|







|
|





|








|




<
<
|
|
<







|

|
|
<
<



|
|
>


|

|
<




















|

|







5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977


5978
5979

5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990


5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001

6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
** use by SQLite, code that links against SQLite is
** permitted to use any of these routines.
**
** The SQLite source code contains multiple implementations
** of these mutex routines.  An appropriate implementation
** is selected automatically at compile-time.  The following
** implementations are available in the SQLite core:
**
** <ul>
** <li>   SQLITE_MUTEX_PTHREADS
** <li>   SQLITE_MUTEX_W32
** <li>   SQLITE_MUTEX_NOOP
** </ul>
**
** The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
** a single-threaded application.  The SQLITE_MUTEX_PTHREADS and
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
** and Windows.
**
** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().
**
** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
** routine returns NULL if it is unable to allocate the requested
** mutex.  The argument to sqlite3_mutex_alloc() must one of these
** integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2
** <li>  SQLITE_MUTEX_STATIC_APP3
** </ul>
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
** cause sqlite3_mutex_alloc() to create
** a new mutex.  ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  SQLite will only request a recursive mutex in
** cases where it really needs one.  If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
** a pointer to a static preexisting mutex.  ^Nine static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  ^For the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
**
** ^The sqlite3_mutex_free() routine deallocates a previously


** allocated dynamic mutex.  Attempting to deallocate a static
** mutex results in undefined behavior.

**
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  ^If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
** upon successful entry.  ^(Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
** In such cases, the
** mutex must be exited an equal number of times before another thread
** can enter.)^  If the same thread tries to enter any mutex other
** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.


**
** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
** will always return SQLITE_BUSY. The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable 
** behavior.)^
**
** ^The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.   The behavior
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated.

**
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
** behave as no-ops.
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);

/*
** CAPI3REF: Mutex Methods Object
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
**
** Usually, the default mutex implementations provided by SQLite are
** sufficient, however the application has the option of substituting a custom
** implementation for specialized deployments or systems for which SQLite
** does not provide a suitable implementation. In this case, the application
** creates and populates an instance of this structure to pass
** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
** Additionally, an instance of this structure can be used as an
** output variable when querying the system for the current mutex
** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
**
** ^The xMutexInit method defined by this structure is invoked as
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe.  ^It must be harmless to
** invoke xMutexInit() multiple times within the same process and without
** intervening calls to xMutexEnd().  Second and subsequent calls to
** xMutexInit() must be no-ops.
**
** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
** and its associates).  ^Similarly, xMutexAlloc() must not use SQLite memory
** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
** memory allocation for a fast or recursive mutex.
**
** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
** called, but only if the prior call to xMutexInit returned SQLITE_OK.
** If xMutexInit fails in any way, it is expected to clean up after itself
** prior to returning.







|




|
|







6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe.  It must be harmless to
** invoke xMutexInit() multiple times within the same process and without
** intervening calls to xMutexEnd().  Second and subsequent calls to
** xMutexInit() must be no-ops.
**
** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
** and its associates).  Similarly, xMutexAlloc() must not use SQLite memory
** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
** memory allocation for a fast or recursive mutex.
**
** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
** called, but only if the prior call to xMutexInit returned SQLITE_OK.
** If xMutexInit fails in any way, it is expected to clean up after itself
** prior to returning.
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
  int (*xMutexNotheld)(sqlite3_mutex *);
};

/*
** CAPI3REF: Mutex Verification Routines
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
** are intended for use inside assert() statements.  ^The SQLite core
** never uses these routines except inside an assert() and applications
** are advised to follow the lead of the core.  ^The SQLite core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag.  ^External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
** ^These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** ^The implementation is not required to provide versions of these
** routines that actually work. If the implementation does not provide working
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
** the routine should return 1.   This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist.  But
** the reason the mutex does not exist is because the build is not
** using mutexes.  And we do not want the assert() containing the
** call to sqlite3_mutex_held() to fail, so a non-zero return is
** the appropriate thing to do.  ^The sqlite3_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif








|

|

|



|


|




|





|







6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
  int (*xMutexNotheld)(sqlite3_mutex *);
};

/*
** CAPI3REF: Mutex Verification Routines
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
** are intended for use inside assert() statements.  The SQLite core
** never uses these routines except inside an assert() and applications
** are advised to follow the lead of the core.  The SQLite core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag.  External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
** These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** The implementation is not required to provide versions of these
** routines that actually work. If the implementation does not provide working
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
** If the argument to sqlite3_mutex_held() is a NULL pointer then
** the routine should return 1.   This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist.  But
** the reason the mutex does not exist is because the build is not
** using mutexes.  And we do not want the assert() containing the
** call to sqlite3_mutex_held() to fail, so a non-zero return is
** the appropriate thing to do.  The sqlite3_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif

6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
#define SQLITE_TESTCTRL_ASSERT                  12
#define SQLITE_TESTCTRL_ALWAYS                  13
#define SQLITE_TESTCTRL_RESERVE                 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS           15
#define SQLITE_TESTCTRL_ISKEYWORD               16
#define SQLITE_TESTCTRL_SCRATCHMALLOC           17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
#define SQLITE_TESTCTRL_EXPLAIN_STMT            19
#define SQLITE_TESTCTRL_NEVER_CORRUPT           20
#define SQLITE_TESTCTRL_VDBE_COVERAGE           21
#define SQLITE_TESTCTRL_BYTEORDER               22
#define SQLITE_TESTCTRL_ISINIT                  23
#define SQLITE_TESTCTRL_SORTER_MMAP             24
#define SQLITE_TESTCTRL_LAST                    24








|







6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
#define SQLITE_TESTCTRL_ASSERT                  12
#define SQLITE_TESTCTRL_ALWAYS                  13
#define SQLITE_TESTCTRL_RESERVE                 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS           15
#define SQLITE_TESTCTRL_ISKEYWORD               16
#define SQLITE_TESTCTRL_SCRATCHMALLOC           17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
#define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
#define SQLITE_TESTCTRL_NEVER_CORRUPT           20
#define SQLITE_TESTCTRL_VDBE_COVERAGE           21
#define SQLITE_TESTCTRL_BYTEORDER               22
#define SQLITE_TESTCTRL_ISINIT                  23
#define SQLITE_TESTCTRL_SORTER_MMAP             24
#define SQLITE_TESTCTRL_LAST                    24

6816
6817
6818
6819
6820
6821
6822




6823
6824
6825
6826
6827
6828
6829
** an [ATTACH] statement for an attached database.
** ^The S and M arguments passed to 
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
** and database name of the source database, respectively.
** ^The source and destination [database connections] (parameters S and D)
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.




**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
** ^The error code and message for the failed call to sqlite3_backup_init()
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
** [sqlite3_errmsg16()] functions.







>
>
>
>







6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
** an [ATTACH] statement for an attached database.
** ^The S and M arguments passed to 
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
** and database name of the source database, respectively.
** ^The source and destination [database connections] (parameters S and D)
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
** there is already a read or read-write transaction open on the 
** destination database.
**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
** ^The error code and message for the failed call to sqlite3_backup_init()
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
** [sqlite3_errmsg16()] functions.
7409
7410
7411
7412
7413
7414
7415




























































































7416
7417
7418
7419
7420
7421
7422
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5































































































/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5

/*
** CAPI3REF: Prepared Statement Scan Status Opcodes
** KEYWORDS: {scanstatus options}
**
** The following constants can be used for the T parameter to the
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface.  Each constant designates a
** different metric for sqlite3_stmt_scanstatus() to return.
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of rows examined by all iterations of the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
** <dd>^The "double" variable pointed to by the T parameter will be set to the
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop.  If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
** product of this value for all prior loops with the same SELECTID will
** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
** <dd>^The "const char *" variable pointed to by the T parameter will be set to 
** a zero-terminated UTF-8 string containing the name of the index or table used
** for the X-th loop.
**
** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
** <dd>^The "const char *" variable pointed to by the T parameter will be set to 
** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description
** for the X-th loop.
**
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
** <dd>^The "int" variable pointed to by the T parameter will be set to the
** "select-id" for the X-th loop.  The select-id identifies which query or
** subquery the loop is part of.  The main query has a select-id of zero.
** The select-id is the same value as is output in the first column
** of an [EXPLAIN QUERY PLAN] query.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP    0
#define SQLITE_SCANSTAT_NVISIT   1
#define SQLITE_SCANSTAT_EST      2
#define SQLITE_SCANSTAT_NAME     3
#define SQLITE_SCANSTAT_EXPLAIN  4
#define SQLITE_SCANSTAT_SELECTID 5

/*
** CAPI3REF: Prepared Statement Scan Status
**
** Return status data for a single loop within query pStmt.
**
** The "iScanStatusOp" parameter determines which status information to return.
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of
** this interface is undefined.
** ^The requested measurement is written into a variable pointed to by
** the "pOut" parameter.
** Parameter "idx" identifies the specific loop to retrieve statistics for.
** Loops are numbered starting from zero. ^If idx is out of range - less than
** zero or greater than or equal to the total number of loops used to implement
** the statement - a non-zero value is returned and the variable that pOut
** points to is unchanged.
**
** ^Statistics might not be available for all loops in all statements. ^In cases
** where there exist loops with no available statistics, this function behaves
** as if the loop did not exist - it returns non-zero and leave the variable
** that pOut points to unchanged.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
  int idx,                  /* Index of loop to report on */
  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
  void *pOut                /* Result written here */
);     

/*
** CAPI3REF: Zero Scan-Status Counters
**
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);


/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
Changes to src/stash.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <assert.h>


/*
** SQL code to implement the tables needed by the stash.
*/
static const char zStashInit[] =
@ CREATE TABLE IF NOT EXISTS %s.stash(
@   stashid INTEGER PRIMARY KEY,     -- Unique stash identifier
@   vid INTEGER,                     -- The baseline check-out for this stash
@   comment TEXT,                    -- Comment for this stash.  Or NULL
@   ctime TIMESTAMP                  -- When the stash was created
@ );
@ CREATE TABLE IF NOT EXISTS %s.stashfile(
@   stashid INTEGER REFERENCES stash,  -- Stash that contains this file
@   rid INTEGER,                       -- Baseline content in BLOB table or 0.
@   isAdded BOOLEAN,                   -- True if this is an added file
@   isRemoved BOOLEAN,                 -- True if this file is deleted
@   isExec BOOLEAN,                    -- True if file is executable
@   isLink BOOLEAN,                    -- True if file is a symlink
@   origname TEXT,                     -- Original filename







|





|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <assert.h>


/*
** SQL code to implement the tables needed by the stash.
*/
static const char zStashInit[] =
@ CREATE TABLE IF NOT EXISTS "%w".stash(
@   stashid INTEGER PRIMARY KEY,     -- Unique stash identifier
@   vid INTEGER,                     -- The baseline check-out for this stash
@   comment TEXT,                    -- Comment for this stash.  Or NULL
@   ctime TIMESTAMP                  -- When the stash was created
@ );
@ CREATE TABLE IF NOT EXISTS "%w".stashfile(
@   stashid INTEGER REFERENCES stash,  -- Stash that contains this file
@   rid INTEGER,                       -- Baseline content in BLOB table or 0.
@   isAdded BOOLEAN,                   -- True if this is an added file
@   isRemoved BOOLEAN,                 -- True if this file is deleted
@   isExec BOOLEAN,                    -- True if file is executable
@   isLink BOOLEAN,                    -- True if file is a symlink
@   origname TEXT,                     -- Original filename
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  Stmt q;               /* Query against the vfile table */
  Stmt ins;             /* Insert statement */

  zFile = mprintf("%/", zFName);
  file_tree_name(zFile, &fname, 1);
  zTreename = blob_str(&fname);
  blob_zero(&sql);
  blob_appendf(&sql,
    "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
    "  FROM vfile"
    " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
    vid
  );
  if( fossil_strcmp(zTreename,".")!=0 ){
    blob_appendf(&sql,
      "   AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
            "  OR pathname=%Q OR origname=%Q)",
      zTreename, zTreename, zTreename, zTreename
    );
  }
  db_prepare(&q, blob_str(&sql));
  blob_reset(&sql);
  db_prepare(&ins,
     "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
                           "origname, newname, delta)"
     "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
     stashid
  );







|






|





|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  Stmt q;               /* Query against the vfile table */
  Stmt ins;             /* Insert statement */

  zFile = mprintf("%/", zFName);
  file_tree_name(zFile, &fname, 1);
  zTreename = blob_str(&fname);
  blob_zero(&sql);
  blob_append_sql(&sql,
    "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
    "  FROM vfile"
    " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
    vid
  );
  if( fossil_strcmp(zTreename,".")!=0 ){
    blob_append_sql(&sql,
      "   AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
            "  OR pathname=%Q OR origname=%Q)",
      zTreename, zTreename, zTreename, zTreename
    );
  }
  db_prepare(&q, "%s", blob_sql_text(&sql));
  blob_reset(&sql);
  db_prepare(&ins,
     "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
                           "origname, newname, delta)"
     "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
     stashid
  );
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  int nCmd;
  int stashid = 0;
  undo_capture_command_line();
  db_must_be_within_tree();
  db_open_config(0);
  db_begin_transaction();
  zDb = db_name("localdb");
  db_multi_exec(zStashInit, zDb, zDb);
  if( g.argc<=2 ){
    zCmd = "save";
  }else{
    zCmd = g.argv[2];
  }
  nCmd = strlen(zCmd);
  if( memcmp(zCmd, "save", nCmd)==0 ){







|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  int nCmd;
  int stashid = 0;
  undo_capture_command_line();
  db_must_be_within_tree();
  db_open_config(0);
  db_begin_transaction();
  zDb = db_name("localdb");
  db_multi_exec(zStashInit /*works-like:"%w,%w"*/, zDb, zDb);
  if( g.argc<=2 ){
    zCmd = "save";
  }else{
    zCmd = g.argv[2];
  }
  nCmd = strlen(zCmd);
  if( memcmp(zCmd, "save", nCmd)==0 ){
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    if( !verboseFlag ){
      verboseFlag = find_option("detail","l",0)!=0; /* deprecated */
    }
    verify_all_options();
    db_prepare(&q,
       "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
       "       comment, datetime(ctime) FROM stash"
       " ORDER BY ctime DESC"
    );
    if( verboseFlag ){
      db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
                      "  FROM stashfile WHERE stashid=$id");
    }
    while( db_step(&q)==SQLITE_ROW ){
      int stashid = db_column_int(&q, 0);







|







532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    if( !verboseFlag ){
      verboseFlag = find_option("detail","l",0)!=0; /* deprecated */
    }
    verify_all_options();
    db_prepare(&q,
       "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
       "       comment, datetime(ctime) FROM stash"
       " ORDER BY ctime"
    );
    if( verboseFlag ){
      db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
                      "  FROM stashfile WHERE stashid=$id");
    }
    while( db_step(&q)==SQLITE_ROW ){
      int stashid = db_column_int(&q, 0);
Changes to src/stat.c.
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163



164
165
166
167
168
169
170


171
172
173
174
175


176
177
178
179
180





181
182
183
184
185
186
187
  @ <tr><th>SQLite&nbsp;Version:</th><td>%.19s(sqlite3_sourceid())
  @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))</td></tr>
  @ <tr><th>Repository Rebuilt:</th><td>
  @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
  @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
  @ <tr><th>Database&nbsp;Stats:</th><td>
  zDb = db_name("repository");
  @ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages,
  @ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page,
  @ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages,
  @ %s(db_text(0, "PRAGMA %s.encoding", zDb)),
  @ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode
  @ </td></tr>

  @ </table>
  style_footer();
}

/*
** COMMAND: dbstat*
**
** Usage: %fossil dbstat ?-brief | -b?
**
** Shows statistics and global information about the repository.
**
** The (-brief|-b) option removes any "long-running" statistics, namely
** those whose calculations are known to slow down as the repository
** grows.
**



*/
void dbstat_cmd(void){
  i64 t, fsize;
  int n, m;
  int szMax, szAvg;
  const char *zDb;
  int brief;


  char zBuf[100];
  const int colWidth = -19 /* printf alignment/width for left column */;
  const char *p;

  brief = find_option("brief", "b",0)!=0;


  db_find_and_open_repository(0,0);

  /* We should be done with options.. */
  verify_all_options();






  fsize = file_size(g.zRepositoryName);
  bigSizeName(sizeof(zBuf), zBuf, fsize);
  fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
  if( !brief ){
    n = db_int(0, "SELECT count(*) FROM blob");
    m = db_int(0, "SELECT count(*) FROM delta");
    fossil_print("%*s%d (stored as %d full text and %d delta blobs)\n",







|
|
|
|
|









|



<
<
|

>
>
>







>
>


|


>
>





>
>
>
>
>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
  @ <tr><th>SQLite&nbsp;Version:</th><td>%.19s(sqlite3_sourceid())
  @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))</td></tr>
  @ <tr><th>Repository Rebuilt:</th><td>
  @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
  @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
  @ <tr><th>Database&nbsp;Stats:</th><td>
  zDb = db_name("repository");
  @ %d(db_int(0, "PRAGMA \"%w\".page_count", zDb)) pages,
  @ %d(db_int(0, "PRAGMA \"%w\".page_size", zDb)) bytes/page,
  @ %d(db_int(0, "PRAGMA \"%w\".freelist_count", zDb)) free pages,
  @ %s(db_text(0, "PRAGMA \"%w\".encoding", zDb)),
  @ %s(db_text(0, "PRAGMA \"%w\".journal_mode", zDb)) mode
  @ </td></tr>

  @ </table>
  style_footer();
}

/*
** COMMAND: dbstat*
**
** Usage: %fossil dbstat OPTIONS
**
** Shows statistics and global information about the repository.
**


** Options:
**
**   --brief|-b           Only show essential elements
**   --db-check           Run a PRAGMA quick_check on the repository database
**   --omit-version-info  Omit the SQLite and Fossil version information
*/
void dbstat_cmd(void){
  i64 t, fsize;
  int n, m;
  int szMax, szAvg;
  const char *zDb;
  int brief;
  int omitVers;            /* Omit Fossil and SQLite version information */
  int dbCheck;             /* True for the --db-check option */
  char zBuf[100];
  const int colWidth = -19 /* printf alignment/width for left column */;
  const char *p, *z;

  brief = find_option("brief", "b",0)!=0;
  omitVers = find_option("omit-version-info", 0, 0)!=0;
  dbCheck = find_option("db-check",0,0)!=0;
  db_find_and_open_repository(0,0);

  /* We should be done with options.. */
  verify_all_options();

  if( (z = db_get("project-name",0))!=0
   || (z = db_get("short-project-name",0))!=0
  ){
    fossil_print("%*s%s\n", colWidth, "project-name:", z);
  }
  fsize = file_size(g.zRepositoryName);
  bigSizeName(sizeof(zBuf), zBuf, fsize);
  fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
  if( !brief ){
    n = db_int(0, "SELECT count(*) FROM blob");
    m = db_int(0, "SELECT count(*) FROM delta");
    fossil_print("%*s%d (stored as %d full text and %d delta blobs)\n",
223
224
225
226
227
228
229





230
231
232
233
234
235
236
237
238


239


240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255



256
257
258
259
260
261
262
263
264
                  " WHERE tagname GLOB 'tkt-*'");
    m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'");
    fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
    n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
    fossil_print("%*s%d\n", colWidth, "events:", n);
    n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
    fossil_print("%*s%d\n", colWidth, "tagchanges:", n);





  }
  n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
                " + 0.99");
  fossil_print("%*s%d days or approximately %.2f years.\n",
               colWidth, "project-age:", n, n/365.2425);
  p = db_get("project-code", 0);
  if( p ){
    fossil_print("%*s%s\n", colWidth, "project-id:", p);
  }


  fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));


  fossil_print("%*s%s %s [%s] (%s)\n",
               colWidth, "fossil-version:",
               MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
               COMPILER_NAME);
  fossil_print("%*s%.19s [%.10s] (%s)\n",
               colWidth, "sqlite-version:",
               sqlite3_sourceid(), &sqlite3_sourceid()[20],
               sqlite3_libversion());

  zDb = db_name("repository");
  fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
               "%s, %s mode\n",
               colWidth, "database-stats:",
               db_int(0, "PRAGMA %s.page_count", zDb),
               db_int(0, "PRAGMA %s.page_size", zDb),
               db_int(0, "PRAGMA %s.freelist_count", zDb),
               db_text(0, "PRAGMA %s.encoding", zDb),



               db_text(0, "PRAGMA %s.journal_mode", zDb));

}

/*
** WEBPAGE: urllist
**
** Show ways in which this repository has been accessed
*/







>
>
>
>
>









>
>

>
>
|
|
|
|
|
|
|
|
>




|
|
|
|
>
>
>
|
|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
                  " WHERE tagname GLOB 'tkt-*'");
    m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'");
    fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
    n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
    fossil_print("%*s%d\n", colWidth, "events:", n);
    n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
    fossil_print("%*s%d\n", colWidth, "tagchanges:", n);
    z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
                   " CAST(julianday('now') - mtime AS INTEGER)"
                   " || ' days ago' FROM event "
                   " ORDER BY mtime DESC LIMIT 1");
    fossil_print("%*s%s\n", colWidth, "latest-change:", z);
  }
  n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
                " + 0.99");
  fossil_print("%*s%d days or approximately %.2f years.\n",
               colWidth, "project-age:", n, n/365.2425);
  p = db_get("project-code", 0);
  if( p ){
    fossil_print("%*s%s\n", colWidth, "project-id:", p);
  }
#if 0
  /* Server-id is not useful information any more */
  fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
#endif
  if( !omitVers ){
    fossil_print("%*s%s %s [%s] (%s)\n",
                 colWidth, "fossil-version:",
                 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
                 COMPILER_NAME);
    fossil_print("%*s%.19s [%.10s] (%s)\n",
                 colWidth, "sqlite-version:",
                 sqlite3_sourceid(), &sqlite3_sourceid()[20],
                 sqlite3_libversion());
  }
  zDb = db_name("repository");
  fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
               "%s, %s mode\n",
               colWidth, "database-stats:",
               db_int(0, "PRAGMA \"%w\".page_count", zDb),
               db_int(0, "PRAGMA \"%w\".page_size", zDb),
               db_int(0, "PRAGMA \"%w\".freelist_count", zDb),
               db_text(0, "PRAGMA \"%w\".encoding", zDb),
               db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
  if( dbCheck ){
    fossil_print("%*s%s\n", colWidth, "database-check:",
                 db_text(0, "PRAGMA quick_check(1)"));
  }
}

/*
** WEBPAGE: urllist
**
** Show ways in which this repository has been accessed
*/
Changes to src/style.c.
173
174
175
176
177
178
179
180
181
182
183
184
185
186



187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
      @ gebi("a%d(i+1)").href="%s(aHref[i])";
    }
  }
  for(i=0; i<nFormAction; i++){
    @ gebi("form%d(i+1)").action="%s(aFormAction[i])";
  }
  @ }
  if( strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT")) ){
    /* Special case for Opera Mini, which executes JS server-side */
    @ var isOperaMini = Object.prototype.toString.call(window.operamini)
    @                   === "[object OperaMini]";
    @ if( isOperaMini ){
    @   setTimeout("setAllHrefs();",%d(nDelay));
    @ }



  }else if( db_get_boolean("auto-hyperlink-mouseover",0) ){

    /* Require mouse movement prior to activating hyperlinks */
    @ document.getElementsByTagName("body")[0].onmousemove=function(){
    @   setTimeout("setAllHrefs();",%d(nDelay));
    @   this.onmousemove = null;
    @ }
  }else{
    /* Active hyperlinks right away */
    @ setTimeout("setAllHrefs();",%d(nDelay));
  }
  @ </script>
}

/*
** Add a new element to the submenu







|






>
>
>

>
|





|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
      @ gebi("a%d(i+1)").href="%s(aHref[i])";
    }
  }
  for(i=0; i<nFormAction; i++){
    @ gebi("form%d(i+1)").action="%s(aFormAction[i])";
  }
  @ }
  if( sqlite3_strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT"))==0 ){
    /* Special case for Opera Mini, which executes JS server-side */
    @ var isOperaMini = Object.prototype.toString.call(window.operamini)
    @                   === "[object OperaMini]";
    @ if( isOperaMini ){
    @   setTimeout("setAllHrefs();",%d(nDelay));
    @ }
  }else if( db_get_boolean("auto-hyperlink-ishuman",0) && g.isHuman ){
    /* Active hyperlinks after a delay */
    @ setTimeout("setAllHrefs();",%d(nDelay));
  }else if( db_get_boolean("auto-hyperlink-mouseover",0) ){
    /* Require mouse movement before starting the teim that will
    ** activating hyperlinks */
    @ document.getElementsByTagName("body")[0].onmousemove=function(){
    @   setTimeout("setAllHrefs();",%d(nDelay));
    @   this.onmousemove = null;
    @ }
  }else{
    /* Active hyperlinks after a delay */
    @ setTimeout("setAllHrefs();",%d(nDelay));
  }
  @ </script>
}

/*
** Add a new element to the submenu
295
296
297
298
299
300
301

302
303
304
305
306
307
308

  if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);

  /* Generate the header up through the main menu */
  Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
  Th_Store("title", zTitle);
  Th_Store("baseurl", g.zBaseURL);

  Th_Store("home", g.zTop);
  Th_Store("index_page", db_get("index-page","/home"));
  if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath);
  Th_Store("current_page", local_zCurrentPage);
  Th_Store("csrf_token", g.zCsrfToken);
  Th_Store("release_version", RELEASE_VERSION);
  Th_Store("manifest_version", MANIFEST_VERSION);







>







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

  if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);

  /* Generate the header up through the main menu */
  Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
  Th_Store("title", zTitle);
  Th_Store("baseurl", g.zBaseURL);
  Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL);
  Th_Store("home", g.zTop);
  Th_Store("index_page", db_get("index-page","/home"));
  if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath);
  Th_Store("current_page", local_zCurrentPage);
  Th_Store("csrf_token", g.zCsrfToken);
  Th_Store("release_version", RELEASE_VERSION);
  Th_Store("manifest_version", MANIFEST_VERSION);
932
933
934
935
936
937
938

939
940
941
942

943
944
945
946

947
948
949
950

951
952
953
954
955
956
957
    @   text-align: right;
    @   vertical-align: top;
    @   white-space: nowrap;
  },
  { "span.ueditInheritNobody",
    "color for capabilities, inherited by nobody",
    @   color: green;

  },
  { "span.ueditInheritDeveloper",
    "color for capabilities, inherited by developer",
    @   color: red;

  },
  { "span.ueditInheritReader",
    "color for capabilities, inherited by reader",
    @   color: black;

  },
  { "span.ueditInheritAnonymous",
    "color for capabilities, inherited by anonymous",
    @   color: blue;

  },
  { "span.capability",
    "format for capabilities, mentioned on the user edit page",
    @   font-weight: bold;
  },
  { "span.usertype",
    "format for different user types, mentioned on the user edit page",







>




>




>




>







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
    @   text-align: right;
    @   vertical-align: top;
    @   white-space: nowrap;
  },
  { "span.ueditInheritNobody",
    "color for capabilities, inherited by nobody",
    @   color: green;
    @   padding: .2em;
  },
  { "span.ueditInheritDeveloper",
    "color for capabilities, inherited by developer",
    @   color: red;
    @   padding: .2em;
  },
  { "span.ueditInheritReader",
    "color for capabilities, inherited by reader",
    @   color: black;
    @   padding: .2em;
  },
  { "span.ueditInheritAnonymous",
    "color for capabilities, inherited by anonymous",
    @   color: blue;
    @   padding: .2em;
  },
  { "span.capability",
    "format for capabilities, mentioned on the user edit page",
    @   font-weight: bold;
  },
  { "span.usertype",
    "format for different user types, mentioned on the user edit page",
1189
1190
1191
1192
1193
1194
1195




1196
1197
1198
1199
1200
1201
1202
  { "tr.row0",
    "even table row color",
    @ /* use default */
  },
  { "tr.row1",
    "odd table row color",
    @ /* Use default */




  },
  { "#canvas", "timeline graph node colors",
    @ color: black;
    @ background-color: white;
  },
  { 0,
    0,







>
>
>
>







1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
  { "tr.row0",
    "even table row color",
    @ /* use default */
  },
  { "tr.row1",
    "odd table row color",
    @ /* Use default */
  },
  { "#usetupEditCapability",
    "format for capabilities string, mentioned on the user edit page",
    @ font-weight: bold;
  },
  { "#canvas", "timeline graph node colors",
    @ color: black;
    @ background-color: white;
  },
  { 0,
    0,
1245
1246
1247
1248
1249
1250
1251

1252
1253
1254
1255
1256
1257
1258
    }
  }

  /* Process through TH1 in order to give an opportunity to substitute
  ** variables such as $baseurl.
  */
  Th_Store("baseurl", g.zBaseURL);

  Th_Store("home", g.zTop);
  image_url_var("logo");
  image_url_var("background");
  Th_Render(blob_str(&css));

  /* Tell CGI that the content returned by this page is considered cacheable */
  g.isConst = 1;







>







1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
    }
  }

  /* Process through TH1 in order to give an opportunity to substitute
  ** variables such as $baseurl.
  */
  Th_Store("baseurl", g.zBaseURL);
  Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL);
  Th_Store("home", g.zTop);
  image_url_var("logo");
  image_url_var("background");
  Th_Render(blob_str(&css));

  /* Tell CGI that the content returned by this page is considered cacheable */
  g.isConst = 1;
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
    style_submenu_element("Hide Cookies", "Hide Cookies",
                          "%s/test_env", g.zTop);
  }
#if !defined(_WIN32)
  @ uid=%d(getuid()), gid=%d(getgid())<br />
#endif
  @ g.zBaseURL = %h(g.zBaseURL)<br />

  @ g.zTop = %h(g.zTop)<br />
  for(i=0, c='a'; c<='z'; c++){
    if( login_has_capability(&c, 1) ) zCap[i++] = c;
  }
  zCap[i] = 0;
  @ g.userUid = %d(g.userUid)<br />
  @ g.zLogin = %h(g.zLogin)<br />







>







1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
    style_submenu_element("Hide Cookies", "Hide Cookies",
                          "%s/test_env", g.zTop);
  }
#if !defined(_WIN32)
  @ uid=%d(getuid()), gid=%d(getgid())<br />
#endif
  @ g.zBaseURL = %h(g.zBaseURL)<br />
  @ g.zHttpsURL = %h(g.zHttpsURL)<br />
  @ g.zTop = %h(g.zTop)<br />
  for(i=0, c='a'; c<='z'; c++){
    if( login_has_capability(&c, 1) ) zCap[i++] = c;
  }
  zCap[i] = 0;
  @ g.userUid = %d(g.userUid)<br />
  @ g.zLogin = %h(g.zLogin)<br />
Changes to src/tag.c.
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
      db_multi_exec(
        "INSERT OR IGNORE INTO private(rid) VALUES(%d);",
        rid
      );
    }
  }
  if( zCol ){
    db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);

    if( tagid==TAG_COMMENT ){
      char *zCopy = mprintf("%s", zValue);
      wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
      free(zCopy);
    }
  }
  if( tagid==TAG_DATE ){







|
>







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
      db_multi_exec(
        "INSERT OR IGNORE INTO private(rid) VALUES(%d);",
        rid
      );
    }
  }
  if( zCol ){
    db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
                  zCol, zValue, rid);
    if( tagid==TAG_COMMENT ){
      char *zCopy = mprintf("%s", zValue);
      wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
      free(zCopy);
    }
  }
  if( tagid==TAG_DATE ){
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
    const char *zType = find_option("type","t",1);
    Blob sql = empty_blob;
    if( zType==0 || zType[0]==0 ) zType = "*";
    if( g.argc!=4 ){
      usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
    }
    if( fRaw ){
      blob_appendf(&sql,
        "SELECT blob.uuid FROM tagxref, blob"
        " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
        "   AND tagxref.tagtype>0"
        "   AND blob.rid=tagxref.rid",
        g.argv[3]
      );
      if( nFindLimit>0 ){
        blob_appendf(&sql, " LIMIT %d", nFindLimit);
      }
      db_prepare(&q, "%s", blob_str(&sql));
      blob_reset(&sql);
      while( db_step(&q)==SQLITE_ROW ){
        fossil_print("%s\n", db_column_text(&q, 0));
      }
      db_finalize(&q);
    }else{
      int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
                         g.argv[3]);
      if( tagid>0 ){
        blob_appendf(&sql,
          "%s"
          "  AND event.type GLOB '%q'"
          "  AND blob.rid IN ("
                    " SELECT rid FROM tagxref"
                    "  WHERE tagtype>0 AND tagid=%d"
                    ")"
          " ORDER BY event.mtime DESC",
          timeline_query_for_tty(), zType, tagid
        );
        db_prepare(&q, "%s", blob_str(&sql));
        blob_reset(&sql);
        print_timeline(&q, nFindLimit, 79, 0);
        db_finalize(&q);
      }
    }
  }else








|







|

|









|









|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
    const char *zType = find_option("type","t",1);
    Blob sql = empty_blob;
    if( zType==0 || zType[0]==0 ) zType = "*";
    if( g.argc!=4 ){
      usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
    }
    if( fRaw ){
      blob_append_sql(&sql,
        "SELECT blob.uuid FROM tagxref, blob"
        " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
        "   AND tagxref.tagtype>0"
        "   AND blob.rid=tagxref.rid",
        g.argv[3]
      );
      if( nFindLimit>0 ){
        blob_append_sql(&sql, " LIMIT %d", nFindLimit);
      }
      db_prepare(&q, "%s", blob_sql_text(&sql));
      blob_reset(&sql);
      while( db_step(&q)==SQLITE_ROW ){
        fossil_print("%s\n", db_column_text(&q, 0));
      }
      db_finalize(&q);
    }else{
      int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
                         g.argv[3]);
      if( tagid>0 ){
        blob_append_sql(&sql,
          "%s"
          "  AND event.type GLOB '%q'"
          "  AND blob.rid IN ("
                    " SELECT rid FROM tagxref"
                    "  WHERE tagtype>0 AND tagid=%d"
                    ")"
          " ORDER BY event.mtime DESC",
          timeline_query_for_tty(), zType, tagid
        );
        db_prepare(&q, "%s", blob_sql_text(&sql));
        blob_reset(&sql);
        print_timeline(&q, nFindLimit, 79, 0);
        db_finalize(&q);
      }
    }
  }else

Changes to src/timeline.c.
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226


227
228
229
230
231
232
233
  GraphContext *pGraph = 0;
  int prevWasDivider = 0;     /* True if previous output row was <hr> */
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */
  int vid = 0;                /* Current checkout version */
  int dateFormat = 0;         /* 0: HH:MM  1: HH:MM:SS
                                 2: YYYY-MM-DD HH:MM
                                 3: YYMMDD HH:MM */

  if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
    vid = db_lget_int("checkout", 0);
  }
  zPrevDate[0] = 0;
  mxWikiLen = db_get_int("timeline-max-comment", 0);
  dateFormat = db_get_int("timeline-date-format", 0);


  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
    /* style is not moved to css, because this is
    ** a technical div for the timeline graph
    */
    @ <div id="canvas" style="position:relative;height:0px;width:0px;"
    @  onclick="clickOnGraph(event)"></div>







|
<
|







>
>







210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
  GraphContext *pGraph = 0;
  int prevWasDivider = 0;     /* True if previous output row was <hr> */
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */
  int vid = 0;                /* Current checkout version */
  int dateFormat = 0;         /* 0: HH:MM (default) */

  const char *zDateFmt;

  if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
    vid = db_lget_int("checkout", 0);
  }
  zPrevDate[0] = 0;
  mxWikiLen = db_get_int("timeline-max-comment", 0);
  dateFormat = db_get_int("timeline-date-format", 0);
  zDateFmt = P("datefmt");
  if( zDateFmt ) dateFormat = atoi(zDateFmt);
  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
    /* style is not moved to css, because this is
    ** a technical div for the timeline graph
    */
    @ <div id="canvas" style="position:relative;height:0px;width:0px;"
    @  onclick="clickOnGraph(event)"></div>
252
253
254
255
256
257
258

259

260
261
262
263
264
265
266
    int tagid = db_column_int(pQuery, 9);
    const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
    const char *zBr = 0;      /* Branch */
    int commentColumn = 3;    /* Column containing comment text */
    int modPending;           /* Pending moderation */
    char zTime[20];


    if( zDate==0 ) zDate = "YYYY-MM-DD HH:MM:SS";  /* Something wrong with the repo */

    modPending =  moderation_pending(rid);
    if( tagid ){
      if( modPending ) tagid = -tagid;
      if( tagid==prevTagid ){
        if( tmFlags & TIMELINE_BRIEF ){
          suppressCnt++;
          continue;







>
|
>







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
    int tagid = db_column_int(pQuery, 9);
    const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
    const char *zBr = 0;      /* Branch */
    int commentColumn = 3;    /* Column containing comment text */
    int modPending;           /* Pending moderation */
    char zTime[20];

    if( zDate==0 ){
      zDate = "YYYY-MM-DD HH:MM:SS";  /* Something wrong with the repo */
    }
    modPending =  moderation_pending(rid);
    if( tagid ){
      if( modPending ) tagid = -tagid;
      if( tagid==prevTagid ){
        if( tmFlags & TIMELINE_BRIEF ){
          suppressCnt++;
          continue;
283
284
285
286
287
288
289







290
291
292
293
294
295
296
297
298



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
      if( !prevWasDivider ){
        @ <tr><td colspan="3"><hr /></td></tr>
      }
      prevWasDivider = 1;
      continue;
    }
    prevWasDivider = 0;







    if( dateFormat<2 ){
      if( fossil_strnicmp(zDate, zPrevDate, 10) ){
        sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
        @ <tr><td>
        @   <div class="divider timelineDate">%s(zPrevDate)</div>
        @ </td><td></td><td></td></tr>
      }
      memcpy(zTime, &zDate[11], 5+dateFormat*3);
      zTime[5+dateFormat*3] = 0;



    }else if(3==dateFormat){
      /* YYMMDD HH:MM */
      int pos = 0;
      zTime[pos++] = zDate[2]; zTime[pos++] = zDate[3]; /* YY */
      zTime[pos++] = zDate[5]; zTime[pos++] = zDate[6]; /* MM */
      zTime[pos++] = zDate[8]; zTime[pos++] = zDate[9]; /* DD */
      zTime[pos++] = ' ';
      zTime[pos++] = zDate[11]; zTime[pos++] = zDate[12]; /* HH */
      zTime[pos++] = ':';
      zTime[pos++] = zDate[14]; zTime[pos++] = zDate[15]; /* MM */
      zTime[pos++] = 0;
    }else{
      /* YYYY-MM-DD HH:MM */
      sqlite3_snprintf(sizeof(zTime), zTime, "%.16s", zDate);
    }
    if( rid == vid ){
      @ <tr class="timelineCurrent">
    }else {
      @ <tr>
    }
    @ <td class="timelineTime">%s(zTime)</td>







>
>
>
>
>
>
>









>
>
>
|











<
|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
      if( !prevWasDivider ){
        @ <tr><td colspan="3"><hr /></td></tr>
      }
      prevWasDivider = 1;
      continue;
    }
    prevWasDivider = 0;
    /* Date format codes:
    **   (0)  HH:MM
    **   (1)  HH:MM:SS
    **   (2)  YYYY-MM-DD HH:MM
    **   (3)  YYMMDD HH:MM
    **   (4)  (off)
    */
    if( dateFormat<2 ){
      if( fossil_strnicmp(zDate, zPrevDate, 10) ){
        sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
        @ <tr><td>
        @   <div class="divider timelineDate">%s(zPrevDate)</div>
        @ </td><td></td><td></td></tr>
      }
      memcpy(zTime, &zDate[11], 5+dateFormat*3);
      zTime[5+dateFormat*3] = 0;
    }else if( 2==dateFormat ){
      /* YYYY-MM-DD HH:MM */
      sqlite3_snprintf(sizeof(zTime), zTime, "%.16s", zDate);
    }else if( 3==dateFormat ){
      /* YYMMDD HH:MM */
      int pos = 0;
      zTime[pos++] = zDate[2]; zTime[pos++] = zDate[3]; /* YY */
      zTime[pos++] = zDate[5]; zTime[pos++] = zDate[6]; /* MM */
      zTime[pos++] = zDate[8]; zTime[pos++] = zDate[9]; /* DD */
      zTime[pos++] = ' ';
      zTime[pos++] = zDate[11]; zTime[pos++] = zDate[12]; /* HH */
      zTime[pos++] = ':';
      zTime[pos++] = zDate[14]; zTime[pos++] = zDate[15]; /* MM */
      zTime[pos++] = 0;
    }else{

      zTime[0] = 0;
    }
    if( rid == vid ){
      @ <tr class="timelineCurrent">
    }else {
      @ <tr>
    }
    @ <td class="timelineTime">%s(zTime)</td>
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
      ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
      wiki_convert(&comment, 0, WIKI_INLINE);
    }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
      Blob truncated;
      blob_zero(&truncated);
      blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
      blob_append(&truncated, "...", 3);
      @ <span class="timelineComment">%w(blob_str(&truncated))</span>
      blob_reset(&truncated);
    }else{
      @ <span class="timelineComment">%w(blob_str(&comment))</span>
    }
    blob_reset(&comment);

    /* Generate the "user: USERNAME" at the end of the comment, together
    ** with a hyperlink to another timeline for that user.
    */
    if( zTagList && zTagList[0]==0 ) zTagList = 0;







|


|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
      ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
      wiki_convert(&comment, 0, WIKI_INLINE);
    }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
      Blob truncated;
      blob_zero(&truncated);
      blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
      blob_append(&truncated, "...", 3);
      @ <span class="timelineComment">%W(blob_str(&truncated))</span>
      blob_reset(&truncated);
    }else{
      @ <span class="timelineComment">%W(blob_str(&comment))</span>
    }
    blob_reset(&comment);

    /* Generate the "user: USERNAME" at the end of the comment, together
    ** with a hyperlink to another timeline for that user.
    */
    if( zTagList && zTagList[0]==0 ) zTagList = 0;
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
    @   etype TEXT,
    @   taglist TEXT,
    @   tagid INTEGER,
    @   short TEXT,
    @   sortby REAL
    @ )
  ;
  db_multi_exec(zSql);
}

/*
** Return a pointer to a constant string that forms the basis
** for a timeline query for the WWW interface.
*/
const char *timeline_query_for_www(void){







|







870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
    @   etype TEXT,
    @   taglist TEXT,
    @   tagid INTEGER,
    @   short TEXT,
    @   sortby REAL
    @ )
  ;
  db_multi_exec("%s", zSql/*safe-for-%s*/);
}

/*
** Return a pointer to a constant string that forms the basis
** for a timeline query for the WWW interface.
*/
const char *timeline_query_for_www(void){
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    @   tagid AS tagid,
    @   brief AS brief,
    @   event.mtime AS mtime
    @  FROM event CROSS JOIN blob
    @ WHERE blob.rid=event.objid
  ;
  if( zBase==0 ){
    zBase = mprintf(zBaseSql, timeline_utc());
  }
  return zBase;
}

/*
** Generate a submenu element with a single parameter change.
*/







|







899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    @   tagid AS tagid,
    @   brief AS brief,
    @   event.mtime AS mtime
    @  FROM event CROSS JOIN blob
    @ WHERE blob.rid=event.objid
  ;
  if( zBase==0 ){
    zBase = mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
  }
  return zBase;
}

/*
** Generate a submenu element with a single parameter change.
*/
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
*/
char *names_of_file(const char *zUuid){
  Stmt q;
  Blob out;
  const char *zSep = "";
  db_prepare(&q,
    "SELECT DISTINCT filename.name FROM mlink, filename"
    " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid='%s')"
    "   AND filename.fnid=mlink.fnid",
    zUuid
  );
  blob_zero(&out);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFN = db_column_text(&q, 0);
    blob_appendf(&out, "%s%z%h</a>", zSep,







|







975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
*/
char *names_of_file(const char *zUuid){
  Stmt q;
  Blob out;
  const char *zSep = "";
  db_prepare(&q,
    "SELECT DISTINCT filename.name FROM mlink, filename"
    " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid=%Q)"
    "   AND filename.fnid=mlink.fnid",
    zUuid
  );
  blob_zero(&out);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFN = db_column_text(&q, 0);
    blob_appendf(&out, "%s%z%h</a>", zSep,
1009
1010
1011
1012
1013
1014
1015

1016
1017
1018
1019
1020
1021
1022
**    nomerge          ... avoid merge links on the path
**    shortest         ... show only the shortest path
**    uf=FUUID       Show only checkins that use given file version
**    brbg           Background color from branch name
**    ubg            Background color from user
**    namechng       Show only checkins that filename changes
**    ym=YYYY-MM     Shown only events for the given year/month.

**
** p= and d= can appear individually or together.  If either p= or d=
** appear, then u=, y=, a=, and b= are ignored.
**
** If a= and b= appear, only a= is used.  If neither appear, the most
** recent events are chosen.
**







>







1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
**    nomerge          ... avoid merge links on the path
**    shortest         ... show only the shortest path
**    uf=FUUID       Show only checkins that use given file version
**    brbg           Background color from branch name
**    ubg            Background color from user
**    namechng       Show only checkins that filename changes
**    ym=YYYY-MM     Shown only events for the given year/month.
**    datefmt=N      Override the date format
**
** p= and d= can appear individually or together.  If either p= or d=
** appear, then u=, y=, a=, and b= are ignored.
**
** If a= and b= appear, only a= is used.  If neither appear, the most
** recent events are chosen.
**
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
  const char *zBefore = P("b");      /* Events before this time */
  const char *zCirca = P("c");       /* Events near this time */
  const char *zTagName = P("t");     /* Show events with this tag */
  const char *zBrName = P("r");      /* Show events related to this tag */
  const char *zSearch = P("s");      /* Search string */
  const char *zUses = P("uf");       /* Only show checkins hold this file */
  const char *zYearMonth = P("ym");  /* Show checkins for the given YYYY-MM */
  const char *zYearWeek = P("yw");   /* Show checkins for the given YYYY-WW (weak-of-year) */
  int useDividers = P("nd")==0;      /* Show dividers if "nd" is missing */
  int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
  int tagid;                         /* Tag ID */
  int tmFlags;                       /* Timeline flags */
  const char *zThisTag = 0;          /* Suppress links to this tag */
  const char *zThisUser = 0;         /* Suppress links to this user */
  HQuery url;                        /* URL for various branch links */







|







1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
  const char *zBefore = P("b");      /* Events before this time */
  const char *zCirca = P("c");       /* Events near this time */
  const char *zTagName = P("t");     /* Show events with this tag */
  const char *zBrName = P("r");      /* Show events related to this tag */
  const char *zSearch = P("s");      /* Search string */
  const char *zUses = P("uf");       /* Only show checkins hold this file */
  const char *zYearMonth = P("ym");  /* Show checkins for the given YYYY-MM */
  const char *zYearWeek = P("yw");   /* Show checkins for the given YYYY-WW (week-of-year)*/
  int useDividers = P("nd")==0;      /* Show dividers if "nd" is missing */
  int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
  int tagid;                         /* Tag ID */
  int tmFlags;                       /* Timeline flags */
  const char *zThisTag = 0;          /* Suppress links to this tag */
  const char *zThisUser = 0;         /* Suppress links to this user */
  HQuery url;                        /* URL for various branch links */
1127
1128
1129
1130
1131
1132
1133

1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
  blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
  blob_append(&sql, timeline_query_for_www(), -1);
  if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
    tmFlags |= TIMELINE_FCHANGES;
    url_add_parameter(&url, "v", 0);
  }
  if( (tmFlags & TIMELINE_UNHIDE)==0 ){

    blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM tagxref"
                 "     WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
                 TAG_HIDDEN);

  }
  if( !useDividers ) url_add_parameter(&url, "nd", 0);
  if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
    /* If from= and to= are present, display all nodes on a path connecting
    ** the two */
    PathNode *p = 0;
    const char *zFrom = 0;







>
|
|
|
>







1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
  blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
  blob_append(&sql, timeline_query_for_www(), -1);
  if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
    tmFlags |= TIMELINE_FCHANGES;
    url_add_parameter(&url, "v", 0);
  }
  if( (tmFlags & TIMELINE_UNHIDE)==0 ){
    blob_append_sql(&sql,
      " AND NOT EXISTS(SELECT 1 FROM tagxref"
      "     WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
      TAG_HIDDEN
    );
  }
  if( !useDividers ) url_add_parameter(&url, "nd", 0);
  if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
    /* If from= and to= are present, display all nodes on a path connecting
    ** the two */
    PathNode *p = 0;
    const char *zFrom = 0;
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
        p = path_first();
      }
      zFrom = P("me");
      zTo = P("you");
    }
    blob_append(&sql, " AND event.objid IN (0", -1);
    while( p ){
      blob_appendf(&sql, ",%d", p->rid);
      p = p->u.pTo;
    }
    blob_append(&sql, ")", -1);
    path_reset();
    blob_append(&desc, "All nodes on the path from ", -1);
    blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
    blob_append(&desc, " to ", -1);
    blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
    tmFlags |= TIMELINE_DISJOINT;
    db_multi_exec("%s", blob_str(&sql));
  }else if( (p_rid || d_rid) && g.perm.Read ){
    /* If p= or d= is present, ignore all other parameters other than n= */
    char *zUuid;
    int np, nd;

    if( p_rid && d_rid ){
      if( p_rid!=d_rid ) p_rid = d_rid;
      if( P("n")==0 ) nEntry = 10;
    }
    db_multi_exec(
       "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
    );
    zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
                         p_rid ? p_rid : d_rid);
    blob_appendf(&sql, " AND event.objid IN ok");
    nd = 0;
    if( d_rid ){
      compute_descendants(d_rid, nEntry+1);
      nd = db_int(0, "SELECT count(*)-1 FROM ok");
      if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
      if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
      if( useDividers ) timeline_add_dividers(0, d_rid);
      db_multi_exec("DELETE FROM ok");
    }
    if( p_rid ){
      compute_ancestors(p_rid, nEntry+1, 0);
      np = db_int(0, "SELECT count(*)-1 FROM ok");
      if( np>0 ){
        if( nd>0 ) blob_appendf(&desc, " and ");
        blob_appendf(&desc, "%d ancestors", np);
        db_multi_exec("%s", blob_str(&sql));
      }
      if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
    }
    blob_appendf(&desc, " of %z[%S]</a>",
                   href("%R/info/%s", zUuid), zUuid);
    if( p_rid ){
      url_add_parameter(&url, "p", zUuid);







|









|














|




|










|







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
        p = path_first();
      }
      zFrom = P("me");
      zTo = P("you");
    }
    blob_append(&sql, " AND event.objid IN (0", -1);
    while( p ){
      blob_append_sql(&sql, ",%d", p->rid);
      p = p->u.pTo;
    }
    blob_append(&sql, ")", -1);
    path_reset();
    blob_append(&desc, "All nodes on the path from ", -1);
    blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
    blob_append(&desc, " to ", -1);
    blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
    tmFlags |= TIMELINE_DISJOINT;
    db_multi_exec("%s", blob_sql_text(&sql));
  }else if( (p_rid || d_rid) && g.perm.Read ){
    /* If p= or d= is present, ignore all other parameters other than n= */
    char *zUuid;
    int np, nd;

    if( p_rid && d_rid ){
      if( p_rid!=d_rid ) p_rid = d_rid;
      if( P("n")==0 ) nEntry = 10;
    }
    db_multi_exec(
       "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
    );
    zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
                         p_rid ? p_rid : d_rid);
    blob_append_sql(&sql, " AND event.objid IN ok");
    nd = 0;
    if( d_rid ){
      compute_descendants(d_rid, nEntry+1);
      nd = db_int(0, "SELECT count(*)-1 FROM ok");
      if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
      if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
      if( useDividers ) timeline_add_dividers(0, d_rid);
      db_multi_exec("DELETE FROM ok");
    }
    if( p_rid ){
      compute_ancestors(p_rid, nEntry+1, 0);
      np = db_int(0, "SELECT count(*)-1 FROM ok");
      if( np>0 ){
        if( nd>0 ) blob_appendf(&desc, " and ");
        blob_appendf(&desc, "%d ancestors", np);
        db_multi_exec("%s", blob_sql_text(&sql));
      }
      if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
    }
    blob_appendf(&desc, " of %z[%S]</a>",
                   href("%R/info/%s", zUuid), zUuid);
    if( p_rid ){
      url_add_parameter(&url, "p", zUuid);
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306

1307
1308
1309

1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
    db_multi_exec(
       "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
       "INSERT INTO ok VALUES(%d);"
       "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
       "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
       f_rid, f_rid, f_rid
    );
    blob_appendf(&sql, " AND event.objid IN ok");
    db_multi_exec("%s", blob_str(&sql));
    if( useDividers ) timeline_add_dividers(0, f_rid);
    blob_appendf(&desc, "Parents and children of check-in ");
    zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
    blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
    tmFlags |= TIMELINE_DISJOINT;
    url_add_parameter(&url, "f", zUuid);
    if( tmFlags & TIMELINE_FCHANGES ){
      timeline_submenu(&url, "Hide Files", "v", 0, 0);
    }else{
      timeline_submenu(&url, "Show Files", "v", "", 0);
    }
    if( (tmFlags & TIMELINE_UNHIDE)==0 ){
      timeline_submenu(&url, "Unhide", "unhide", "", 0);
    }
  }else{
    /* Otherwise, a timeline based on a span of time */
    int n;
    const char *zEType = "timeline item";
    char *zDate;
    if( zUses ){
      blob_appendf(&sql, " AND event.objid IN usesfile ");
    }
    if( renameOnly ){
      blob_appendf(&sql, " AND event.objid IN rnfile ");
    }
    if( zYearMonth ){
      blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
                   zYearMonth);
    }
    else if( zYearWeek ){
      blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
                   zYearWeek);
    }
    if( tagid>0 ){
      blob_appendf(&sql,
        "AND (EXISTS(SELECT 1 FROM tagxref"
                    " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);

      if( zBrName ){
        url_add_parameter(&url, "r", zBrName);
        /* The next two blob_appendf() calls add SQL that causes checkins that
        ** are not part of the branch which are parents or children of the
        ** branch to be included in the report.  This related check-ins are
        ** useful in helping to visualize what has happened on a quiescent
        ** branch that is infrequently merged with a much more activate branch.
        */
        blob_appendf(&sql,
          " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
                     " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
           tagid
        );
        if( (tmFlags & TIMELINE_UNHIDE)==0 ){
          blob_appendf(&sql,
            " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
                       " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
            TAG_HIDDEN
          );
        }
        if( P("mionly")==0 ){
          blob_appendf(&sql,
            " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
                       " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
            tagid
          );
          if( (tmFlags & TIMELINE_UNHIDE)==0 ){

            blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
                       " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
                         TAG_HIDDEN);

          }
        }else{
          url_add_parameter(&url, "mionly", "1");
        }
      }else{
        url_add_parameter(&url, "t", zTagName);
      }
      blob_appendf(&sql, ")");
    }
    if( (zType[0]=='w' && !g.perm.RdWiki)
     || (zType[0]=='t' && !g.perm.RdTkt)
     || (zType[0]=='e' && !g.perm.RdWiki)
     || (zType[0]=='c' && !g.perm.Read)
     || (zType[0]=='g' && !g.perm.Read)
    ){
      zType = "all";
    }
    if( zType[0]=='a' ){
      if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
        char cSep = '(';
        blob_appendf(&sql, " AND event.type IN ");
        if( g.perm.Read ){
          blob_appendf(&sql, "%c'ci','g'", cSep);
          cSep = ',';
        }
        if( g.perm.RdWiki ){
          blob_appendf(&sql, "%c'w','e'", cSep);
          cSep = ',';
        }
        if( g.perm.RdTkt ){
          blob_appendf(&sql, "%c't'", cSep);
          cSep = ',';
        }
        blob_appendf(&sql, ")");
      }
    }else{ /* zType!="all" */
      blob_appendf(&sql, " AND event.type=%Q", zType);
      url_add_parameter(&url, "y", zType);
      if( zType[0]=='c' ){
        zEType = "checkin";
      }else if( zType[0]=='w' ){
        zEType = "wiki edit";
      }else if( zType[0]=='t' ){
        zEType = "ticket change";
      }else if( zType[0]=='e' ){
        zEType = "event";
      }else if( zType[0]=='g' ){
        zEType = "tag";
      }
    }
    if( zUser ){
      blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
                   zUser, zUser);
      url_add_parameter(&url, "u", zUser);
      zThisUser = zUser;
    }
    if( zSearch ){
      blob_appendf(&sql,
        " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
        zSearch, zSearch);
      url_add_parameter(&url, "s", zSearch);
    }
    rBefore = symbolic_name_to_mtime(zBefore);
    rAfter = symbolic_name_to_mtime(zAfter);
    rCirca = symbolic_name_to_mtime(zCirca);
    if( rAfter>0.0 ){
      if( rBefore>0.0 ){
        blob_appendf(&sql,
           " AND event.mtime>=%.17g AND event.mtime<=%.17g"
           " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
        url_add_parameter(&url, "a", zAfter);
        url_add_parameter(&url, "b", zBefore);
        nEntry = 1000000;
      }else{
        blob_appendf(&sql,
           " AND event.mtime>=%.17g  ORDER BY event.mtime ASC",
           rAfter-ONE_SECOND);
        url_add_parameter(&url, "a", zAfter);
      }
    }else if( rBefore>0.0 ){
      blob_appendf(&sql,
         " AND event.mtime<=%.17g ORDER BY event.mtime DESC",
         rBefore+ONE_SECOND);
      url_add_parameter(&url, "b", zBefore);
    }else if( rCirca>0.0 ){
      Blob sql2;
      blob_init(&sql2, blob_str(&sql), -1);
      blob_appendf(&sql2,
          " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
          rCirca, (nEntry+1)/2
      );
      db_multi_exec("%s", blob_str(&sql2));
      blob_reset(&sql2);
      blob_appendf(&sql,
          " AND event.mtime>=%f ORDER BY event.mtime ASC",
          rCirca
      );
      nEntry -= (nEntry+1)/2;
      if( useDividers ) timeline_add_dividers(rCirca, 0);
      url_add_parameter(&url, "c", zCirca);
    }else{
      blob_appendf(&sql, " ORDER BY event.mtime DESC");
    }
    blob_appendf(&sql, " LIMIT %d", nEntry);
    db_multi_exec("%s", blob_str(&sql));

    n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
    if( zYearMonth ){
      blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
    }else if( zYearWeek ){
      blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
    }else if( zAfter==0 && zBefore==0 && zCirca==0 ){







|
|




















|


|


|



|



|











|





|






|





>
|
|
|
>







|












|

|



|



|


|


|














|





|









|






|





|





|
|



|

|







|

|
|







1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
    db_multi_exec(
       "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
       "INSERT INTO ok VALUES(%d);"
       "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
       "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
       f_rid, f_rid, f_rid
    );
    blob_append_sql(&sql, " AND event.objid IN ok");
    db_multi_exec("%s", blob_sql_text(&sql));
    if( useDividers ) timeline_add_dividers(0, f_rid);
    blob_appendf(&desc, "Parents and children of check-in ");
    zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
    blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
    tmFlags |= TIMELINE_DISJOINT;
    url_add_parameter(&url, "f", zUuid);
    if( tmFlags & TIMELINE_FCHANGES ){
      timeline_submenu(&url, "Hide Files", "v", 0, 0);
    }else{
      timeline_submenu(&url, "Show Files", "v", "", 0);
    }
    if( (tmFlags & TIMELINE_UNHIDE)==0 ){
      timeline_submenu(&url, "Unhide", "unhide", "", 0);
    }
  }else{
    /* Otherwise, a timeline based on a span of time */
    int n;
    const char *zEType = "timeline item";
    char *zDate;
    if( zUses ){
      blob_append_sql(&sql, " AND event.objid IN usesfile ");
    }
    if( renameOnly ){
      blob_append_sql(&sql, " AND event.objid IN rnfile ");
    }
    if( zYearMonth ){
      blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
                   zYearMonth);
    }
    else if( zYearWeek ){
      blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
                   zYearWeek);
    }
    if( tagid>0 ){
      blob_append_sql(&sql,
        "AND (EXISTS(SELECT 1 FROM tagxref"
                    " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);

      if( zBrName ){
        url_add_parameter(&url, "r", zBrName);
        /* The next two blob_appendf() calls add SQL that causes checkins that
        ** are not part of the branch which are parents or children of the
        ** branch to be included in the report.  This related check-ins are
        ** useful in helping to visualize what has happened on a quiescent
        ** branch that is infrequently merged with a much more activate branch.
        */
        blob_append_sql(&sql,
          " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
                     " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
           tagid
        );
        if( (tmFlags & TIMELINE_UNHIDE)==0 ){
          blob_append_sql(&sql,
            " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
                       " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
            TAG_HIDDEN
          );
        }
        if( P("mionly")==0 ){
          blob_append_sql(&sql,
            " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
                       " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
            tagid
          );
          if( (tmFlags & TIMELINE_UNHIDE)==0 ){
            blob_append_sql(&sql, 
              " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
              " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
              TAG_HIDDEN
            );
          }
        }else{
          url_add_parameter(&url, "mionly", "1");
        }
      }else{
        url_add_parameter(&url, "t", zTagName);
      }
      blob_append_sql(&sql, ")");
    }
    if( (zType[0]=='w' && !g.perm.RdWiki)
     || (zType[0]=='t' && !g.perm.RdTkt)
     || (zType[0]=='e' && !g.perm.RdWiki)
     || (zType[0]=='c' && !g.perm.Read)
     || (zType[0]=='g' && !g.perm.Read)
    ){
      zType = "all";
    }
    if( zType[0]=='a' ){
      if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
        char cSep = '(';
        blob_append_sql(&sql, " AND event.type IN ");
        if( g.perm.Read ){
          blob_append_sql(&sql, "%c'ci','g'", cSep);
          cSep = ',';
        }
        if( g.perm.RdWiki ){
          blob_append_sql(&sql, "%c'w','e'", cSep);
          cSep = ',';
        }
        if( g.perm.RdTkt ){
          blob_append_sql(&sql, "%c't'", cSep);
          cSep = ',';
        }
        blob_append_sql(&sql, ")");
      }
    }else{ /* zType!="all" */
      blob_append_sql(&sql, " AND event.type=%Q", zType);
      url_add_parameter(&url, "y", zType);
      if( zType[0]=='c' ){
        zEType = "checkin";
      }else if( zType[0]=='w' ){
        zEType = "wiki edit";
      }else if( zType[0]=='t' ){
        zEType = "ticket change";
      }else if( zType[0]=='e' ){
        zEType = "event";
      }else if( zType[0]=='g' ){
        zEType = "tag";
      }
    }
    if( zUser ){
      blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)",
                   zUser, zUser);
      url_add_parameter(&url, "u", zUser);
      zThisUser = zUser;
    }
    if( zSearch ){
      blob_append_sql(&sql,
        " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
        zSearch, zSearch);
      url_add_parameter(&url, "s", zSearch);
    }
    rBefore = symbolic_name_to_mtime(zBefore);
    rAfter = symbolic_name_to_mtime(zAfter);
    rCirca = symbolic_name_to_mtime(zCirca);
    if( rAfter>0.0 ){
      if( rBefore>0.0 ){
        blob_append_sql(&sql,
           " AND event.mtime>=%.17g AND event.mtime<=%.17g"
           " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
        url_add_parameter(&url, "a", zAfter);
        url_add_parameter(&url, "b", zBefore);
        nEntry = 1000000;
      }else{
        blob_append_sql(&sql,
           " AND event.mtime>=%.17g  ORDER BY event.mtime ASC",
           rAfter-ONE_SECOND);
        url_add_parameter(&url, "a", zAfter);
      }
    }else if( rBefore>0.0 ){
      blob_append_sql(&sql,
         " AND event.mtime<=%.17g ORDER BY event.mtime DESC",
         rBefore+ONE_SECOND);
      url_add_parameter(&url, "b", zBefore);
    }else if( rCirca>0.0 ){
      Blob sql2;
      blob_init(&sql2, blob_sql_text(&sql), -1);
      blob_append_sql(&sql2,
          " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
          rCirca, (nEntry+1)/2
      );
      db_multi_exec("%s", blob_sql_text(&sql2));
      blob_reset(&sql2);
      blob_append_sql(&sql,
          " AND event.mtime>=%f ORDER BY event.mtime ASC",
          rCirca
      );
      nEntry -= (nEntry+1)/2;
      if( useDividers ) timeline_add_dividers(rCirca, 0);
      url_add_parameter(&url, "c", zCirca);
    }else{
      blob_append_sql(&sql, " ORDER BY event.mtime DESC");
    }
    blob_append_sql(&sql, " LIMIT %d", nEntry);
    db_multi_exec("%s", blob_sql_text(&sql));

    n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
    if( zYearMonth ){
      blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
    }else if( zYearWeek ){
      blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
    }else if( zAfter==0 && zBefore==0 && zCirca==0 ){
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
        if( (tmFlags & TIMELINE_UNHIDE)==0 ){
          timeline_submenu(&url, "Unhide", "unhide", "", 0);
        }
      }
    }
  }
  if( P("showsql") ){
    @ <blockquote>%h(blob_str(&sql))</blockquote>
  }
  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
  db_finalize(&q);







|







1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
        if( (tmFlags & TIMELINE_UNHIDE)==0 ){
          timeline_submenu(&url, "Unhide", "unhide", "", 0);
        }
      }
    }
  }
  if( P("showsql") ){
    @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
  }
  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
  db_finalize(&q);
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726


1727
1728
1729
1730
1731
1732
1733
}

/*
** Return a pointer to a static string that forms the basis for
** a timeline query for display on a TTY.
*/
const char *timeline_query_for_tty(void){
  static const char *zBase = 0;
  static const char zBaseSql[] =
    @ SELECT
    @   blob.rid AS rid,
    @   uuid,
    @   datetime(event.mtime%s) AS mDateTime,
    @   coalesce(ecomment,comment)
    @     || ' (user: ' || coalesce(euser,user,'?')
    @     || (SELECT case when length(x)>0 then ' tags: ' || x else '' end
    @           FROM (SELECT group_concat(substr(tagname,5), ', ') AS x
    @                   FROM tag, tagxref
    @                  WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
    @                    AND tagxref.rid=blob.rid AND tagxref.tagtype>0))
    @     || ')' as comment,
    @   (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim)
    @        AS primPlinkCount,
    @   (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
    @   event.mtime AS mtime,
    @   tagxref.value AS branch
    @ FROM tag CROSS JOIN event CROSS JOIN blob
    @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
    @   AND tagxref.tagtype>0
    @   AND tagxref.rid=blob.rid
    @ WHERE blob.rid=event.objid
    @   AND tag.tagname='branch'
  ;
  if( zBase==0 ){
    zBase = mprintf(zBaseSql, timeline_utc());
  }
  return zBase;
}

/*
** Return true if the input string is a date in the ISO 8601 format:
** YYYY-MM-DD.
*/
static int isIsoDate(const char *z){
  return strlen(z)==10
      && z[4]=='-'
      && z[7]=='-'
      && fossil_isdigit(z[0])
      && fossil_isdigit(z[5]);
}

/*
** COMMAND: timeline
**
** Usage: %fossil timeline ?WHEN? ?BASELINE|DATETIME? ?OPTIONS?
**
** Print a summary of activity going backwards in date and time
** specified or from the current date and time if no arguments
** are given.  The WHEN argument can be any unique abbreviation
** of one of these keywords:
**
**     before
**     after
**     descendants | children
**     ancestors | parents
**
** The BASELINE can be any unique prefix of 4 characters or more.
** The DATETIME should be in the ISO8601 format.  For
** examples: "2007-08-18 07:21:21".  You can also say "current"
** for the current version or "now" for the current time.
**
** Options:
**   -n|--limit N         Output the first N entries (default 20 lines).
**                        N=0 means no limit.


**   --offset P           skip P changes
**   -t|--type TYPE       Output items from the given types only, such as:
**                            ci = file commits only
**                            e  = events only
**                            t  = tickets only
**                            w  = wiki commits only
**   -v|--verbose         Output the list of files changed by each commit







<



















|





<
|
<
<

















|



















>
>







1670
1671
1672
1673
1674
1675
1676

1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701

1702


1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
}

/*
** Return a pointer to a static string that forms the basis for
** a timeline query for display on a TTY.
*/
const char *timeline_query_for_tty(void){

  static const char zBaseSql[] =
    @ SELECT
    @   blob.rid AS rid,
    @   uuid,
    @   datetime(event.mtime%s) AS mDateTime,
    @   coalesce(ecomment,comment)
    @     || ' (user: ' || coalesce(euser,user,'?')
    @     || (SELECT case when length(x)>0 then ' tags: ' || x else '' end
    @           FROM (SELECT group_concat(substr(tagname,5), ', ') AS x
    @                   FROM tag, tagxref
    @                  WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
    @                    AND tagxref.rid=blob.rid AND tagxref.tagtype>0))
    @     || ')' as comment,
    @   (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim)
    @        AS primPlinkCount,
    @   (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
    @   event.mtime AS mtime,
    @   tagxref.value AS branch
    @ FROM tag CROSS JOIN event CROSS JOIN blob
    @      LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
    @   AND tagxref.tagtype>0
    @   AND tagxref.rid=blob.rid
    @ WHERE blob.rid=event.objid
    @   AND tag.tagname='branch'
  ;

  return mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());


}

/*
** Return true if the input string is a date in the ISO 8601 format:
** YYYY-MM-DD.
*/
static int isIsoDate(const char *z){
  return strlen(z)==10
      && z[4]=='-'
      && z[7]=='-'
      && fossil_isdigit(z[0])
      && fossil_isdigit(z[5]);
}

/*
** COMMAND: timeline
**
** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS?
**
** Print a summary of activity going backwards in date and time
** specified or from the current date and time if no arguments
** are given.  The WHEN argument can be any unique abbreviation
** of one of these keywords:
**
**     before
**     after
**     descendants | children
**     ancestors | parents
**
** The BASELINE can be any unique prefix of 4 characters or more.
** The DATETIME should be in the ISO8601 format.  For
** examples: "2007-08-18 07:21:21".  You can also say "current"
** for the current version or "now" for the current time.
**
** Options:
**   -n|--limit N         Output the first N entries (default 20 lines).
**                        N=0 means no limit.
**   -p|--path PATH       Output items affecting PATH only. 
**                        PATH can be a file or a sub directory.
**   --offset P           skip P changes
**   -t|--type TYPE       Output items from the given types only, such as:
**                            ci = file commits only
**                            e  = events only
**                            t  = tickets only
**                            w  = wiki commits only
**   -v|--verbose         Output the list of files changed by each commit
1750
1751
1752
1753
1754
1755
1756


1757
1758
1759
1760
1761
1762
1763
1764
1765


1766
1767
1768
1769
1770
1771
1772
  char *zDate;
  Blob sql;
  int objid = 0;
  Blob uuid;
  int mode = 0 ;       /* 0:none  1: before  2:after  3:children  4:parents */
  int verboseFlag = 0 ;
  int iOffset;



  verboseFlag = find_option("verbose","v", 0)!=0;
  if( !verboseFlag){
    verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
  }
  db_find_and_open_repository(0, 0);
  zLimit = find_option("limit","n",1);
  zWidth = find_option("width","W",1);
  zType = find_option("type","t",1);


  if( !zLimit ){
    zLimit = find_option("count",0,1);
  }
  if( zLimit ){
    n = atoi(zLimit);
  }else{
    n = -20;







>
>









>
>







1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
  char *zDate;
  Blob sql;
  int objid = 0;
  Blob uuid;
  int mode = 0 ;       /* 0:none  1: before  2:after  3:children  4:parents */
  int verboseFlag = 0 ;
  int iOffset;
  const char *zFilePattern = 0;
  Blob treeName;

  verboseFlag = find_option("verbose","v", 0)!=0;
  if( !verboseFlag){
    verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
  }
  db_find_and_open_repository(0, 0);
  zLimit = find_option("limit","n",1);
  zWidth = find_option("width","W",1);
  zType = find_option("type","t",1);
  zFilePattern = find_option("path","p",1);

  if( !zLimit ){
    zLimit = find_option("count",0,1);
  }
  if( zLimit ){
    n = atoi(zLimit);
  }else{
    n = -20;
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
    }else if( strncmp(g.argv[2],"children",k)==0 ){
      mode = 3;
    }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
      mode = 4;
    }else if( strncmp(g.argv[2],"parents",k)==0 ){
      mode = 4;
    }else if(!zType && !zLimit){
      usage("?WHEN? ?BASELINE|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
            "?-W|--width WIDTH?");
    }
    if( '-' != *g.argv[3] ){
      zOrigin = g.argv[3];
    }else{
      zOrigin = "now";
    }
  }else if( g.argc==3 ){







|
|







1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
    }else if( strncmp(g.argv[2],"children",k)==0 ){
      mode = 3;
    }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
      mode = 4;
    }else if( strncmp(g.argv[2],"parents",k)==0 ){
      mode = 4;
    }else if(!zType && !zLimit){
      usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
            "?-W|--width WIDTH? ?-p|--path PATH");
    }
    if( '-' != *g.argv[3] ){
      zOrigin = g.argv[3];
    }else{
      zOrigin = "now";
    }
  }else if( g.argc==3 ){
1836
1837
1838
1839
1840
1841
1842















1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862




















1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
      fossil_fatal("cannot compute descendants or ancestors of a date");
    }
    if( mode==0 ){
      if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
    }
    zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
  }















  if( mode==0 ) mode = 1;
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_tty(), -1);
  blob_appendf(&sql, "  AND event.mtime %s %s",
     (mode==1 || mode==4) ? "<=" : ">=",
     zDate
  );

  if( mode==3 || mode==4 ){
    db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
    if( mode==3 ){
      compute_descendants(objid, n);
    }else{
      compute_ancestors(objid, n, 0);
    }
    blob_appendf(&sql, " AND blob.rid IN ok");
  }
  if( zType && (zType[0]!='a') ){
    blob_appendf(&sql, " AND event.type=%Q ", zType);
  }




















  blob_appendf(&sql, " ORDER BY event.mtime DESC");
  if( iOffset>0 ){
    /* Don't handle LIMIT here, otherwise print_timeline()
     * will not determine the end-marker correctly! */
    blob_appendf(&sql, " LIMIT -1 OFFSET %d", iOffset);
  }
  db_prepare(&q, blob_str(&sql));
  blob_reset(&sql);
  print_timeline(&q, n, width, verboseFlag);
  db_finalize(&q);
}

/*
** Return one of two things:







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

|









|


|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|



|

|







1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
      fossil_fatal("cannot compute descendants or ancestors of a date");
    }
    if( mode==0 ){
      if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
    }
    zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
  }
  
  if( zFilePattern ){
    if( zType==0 ){
      /* When zFilePattern is specified and type is not specified, only show
       * file checkins */
      zType="ci";
    }
    file_tree_name(zFilePattern, &treeName, 1);
    if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
      /* When zTreeName refers to g.zLocalRoot, it's like not specifying
       * zFilePattern. */
      zFilePattern = 0;
    }
  }

  if( mode==0 ) mode = 1;
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_tty(), -1);
  blob_append_sql(&sql, "  AND event.mtime %s %s",
     (mode==1 || mode==4) ? "<=" : ">=",
     zDate /*safe-for-%s*/
  );

  if( mode==3 || mode==4 ){
    db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
    if( mode==3 ){
      compute_descendants(objid, n);
    }else{
      compute_ancestors(objid, n, 0);
    }
    blob_append_sql(&sql, "\n  AND blob.rid IN ok");
  }
  if( zType && (zType[0]!='a') ){
    blob_append_sql(&sql, "\n  AND event.type=%Q ", zType);
  }
  if( zFilePattern ){
    blob_append(&sql,
       "\n  AND EXISTS(SELECT 1 FROM mlink\n"
         "              WHERE mlink.mid=event.objid\n"
         "                AND mlink.fnid IN ", -1);
    if( filenames_are_case_sensitive() ){
      blob_append_sql(&sql,
        "(SELECT fnid FROM filename"
        " WHERE name=%Q"
        " OR name GLOB '%q/*')",
        blob_str(&treeName), blob_str(&treeName));
    }else{
      blob_append_sql(&sql,
        "(SELECT fnid FROM filename"
        " WHERE name=%Q COLLATE nocase"
        " OR lower(name) GLOB lower('%q/*'))",
        blob_str(&treeName), blob_str(&treeName));
    }
    blob_append(&sql, ")", -1);
  }
  blob_append_sql(&sql, "\nORDER BY event.mtime DESC");
  if( iOffset>0 ){
    /* Don't handle LIMIT here, otherwise print_timeline()
     * will not determine the end-marker correctly! */
    blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset);
  }
  db_prepare(&q, "%s", blob_sql_text(&sql));
  blob_reset(&sql);
  print_timeline(&q, n, width, verboseFlag);
  db_finalize(&q);
}

/*
** Return one of two things:
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
  int iterations = 0;                /* number of weeks/months we iterate
                                        over */
  stats_report_init_view();
  stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
  blob_appendf(&header, "Timeline Events (%s) by year%s",
               stats_report_label_for_type(),
               (includeMonth ? "/month" : ""));
  blob_appendf(&sql,
               "SELECT substr(date(mtime),1,%d) AS timeframe, "
               "count(*) AS eventCount "
               "FROM v_reports ",
               includeMonth ? 7 : 4);
  if(zUserName&&*zUserName){
    blob_appendf(&sql, " WHERE user=%Q ", zUserName);
    blob_appendf(&header," for user %q", zUserName);
  }
  blob_append(&sql,
              " GROUP BY timeframe"
              " ORDER BY timeframe DESC",
              -1);
  db_prepare(&query, blob_str(&sql));
  blob_reset(&sql);
  @ <h1>%b(&header)</h1>
  @ <table class='statistics-report-table-events' border='0' cellpadding='2'
  @  cellspacing='0' id='statsTable'>
  @ <thead>
  @ <th>%s(zTimeLabel)</th>
  @ <th>Events</th>







|





|






|







2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
  int iterations = 0;                /* number of weeks/months we iterate
                                        over */
  stats_report_init_view();
  stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
  blob_appendf(&header, "Timeline Events (%s) by year%s",
               stats_report_label_for_type(),
               (includeMonth ? "/month" : ""));
  blob_append_sql(&sql,
               "SELECT substr(date(mtime),1,%d) AS timeframe, "
               "count(*) AS eventCount "
               "FROM v_reports ",
               includeMonth ? 7 : 4);
  if(zUserName&&*zUserName){
    blob_append_sql(&sql, " WHERE user=%Q ", zUserName);
    blob_appendf(&header," for user %q", zUserName);
  }
  blob_append(&sql,
              " GROUP BY timeframe"
              " ORDER BY timeframe DESC",
              -1);
  db_prepare(&query, "%s", blob_sql_text(&sql));
  blob_reset(&sql);
  @ <h1>%b(&header)</h1>
  @ <table class='statistics-report-table-events' border='0' cellpadding='2'
  @  cellspacing='0' id='statsTable'>
  @ <thead>
  @ <th>%s(zTimeLabel)</th>
  @ <th>Events</th>
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
*/
static void stats_report_by_user(){
  Stmt query = empty_Stmt;
  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */
  Blob sql = empty_blob;             /* SQL */
  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */
  stats_report_init_view();
  stats_report_event_types_menu("byuser", NULL);
  blob_append(&sql,
               "SELECT user, "
               "COUNT(*) AS eventCount "
               "FROM v_reports "
               "GROUP BY user ORDER BY eventCount DESC",
              -1);
  db_prepare(&query, blob_str(&sql));
  blob_reset(&sql);
  @ <h1>Timeline Events
  @ (%s(stats_report_label_for_type())) by User</h1>
  @ <table class='statistics-report-table-events' border='0'
  @ cellpadding='2' cellspacing='0' id='statsTable'>
  @ <thead><tr>
  @ <th>User</th>
  @ <th>Events</th>







<




|



|
<
<
<







2373
2374
2375
2376
2377
2378
2379

2380
2381
2382
2383
2384
2385
2386
2387
2388



2389
2390
2391
2392
2393
2394
2395
*/
static void stats_report_by_user(){
  Stmt query = empty_Stmt;
  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */

  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */
  stats_report_init_view();
  stats_report_event_types_menu("byuser", NULL);
  db_prepare(&query,
               "SELECT user, "
               "COUNT(*) AS eventCount "
               "FROM v_reports "
               "GROUP BY user ORDER BY eventCount DESC");



  @ <h1>Timeline Events
  @ (%s(stats_report_label_for_type())) by User</h1>
  @ <table class='statistics-report-table-events' border='0'
  @ cellpadding='2' cellspacing='0' id='statsTable'>
  @ <thead><tr>
  @ <th>User</th>
  @ <th>Events</th>
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
*/
static void stats_report_day_of_week(){
  Stmt query = empty_Stmt;
  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */
  Blob sql = empty_blob;             /* SQL */
  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */
  static const char *const daysOfWeek[] = {
  "Monday", "Tuesday", "Wednesday", "Thursday",
  "Friday", "Saturday", "Sunday"
  };

  stats_report_init_view();
  stats_report_event_types_menu("byweekday", NULL);
  blob_append(&sql,
               "SELECT cast(mtime %% 7 AS INTEGER) dow, "
               "COUNT(*) AS eventCount "
               "FROM v_reports "
               "GROUP BY dow ORDER BY dow",
              -1);
  db_prepare(&query, blob_str(&sql));
  blob_reset(&sql);
  @ <h1>Timeline Events
  @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
  @ <table class='statistics-report-table-events' border='0'
  @ cellpadding='2' cellspacing='0' id='statsTable'>
  @ <thead><tr>
  @ <th>DoW</th>
  @ <th>Day</th>







<









|



|
<
<
<







2436
2437
2438
2439
2440
2441
2442

2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456



2457
2458
2459
2460
2461
2462
2463
*/
static void stats_report_day_of_week(){
  Stmt query = empty_Stmt;
  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */

  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */
  static const char *const daysOfWeek[] = {
  "Monday", "Tuesday", "Wednesday", "Thursday",
  "Friday", "Saturday", "Sunday"
  };

  stats_report_init_view();
  stats_report_event_types_menu("byweekday", NULL);
  db_prepare(&query,
               "SELECT cast(mtime %% 7 AS INTEGER) dow, "
               "COUNT(*) AS eventCount "
               "FROM v_reports "
               "GROUP BY dow ORDER BY dow");



  @ <h1>Timeline Events
  @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
  @ <table class='statistics-report-table-events' border='0'
  @ cellpadding='2' cellspacing='0' id='statsTable'>
  @ <thead><tr>
  @ <th>DoW</th>
  @ <th>Day</th>
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
  }else{
    stats_report_event_types_menu("byweek", NULL);
  }
  blob_append(&sql,
              "SELECT DISTINCT substr(date(mtime),1,4) AS y "
              "FROM v_reports WHERE 1 ", -1);
  if(zUserName&&*zUserName){
    blob_appendf(&sql,"AND user=%Q ", zUserName);
  }
  blob_append(&sql,"GROUP BY y ORDER BY y", -1);
  db_prepare(&qYears, blob_str(&sql));
  blob_reset(&sql);
  cgi_printf("Select year: ");
  while( SQLITE_ROW == db_step(&qYears) ){
    const char *zT = db_column_text(&qYears, 0);
    if( i++ ){
      cgi_printf(" ");
    }







|


|







2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
  }else{
    stats_report_event_types_menu("byweek", NULL);
  }
  blob_append(&sql,
              "SELECT DISTINCT substr(date(mtime),1,4) AS y "
              "FROM v_reports WHERE 1 ", -1);
  if(zUserName&&*zUserName){
    blob_append_sql(&sql,"AND user=%Q ", zUserName);
  }
  blob_append(&sql,"GROUP BY y ORDER BY y", -1);
  db_prepare(&qYears, "%s", blob_sql_text(&sql));
  blob_reset(&sql);
  cgi_printf("Select year: ");
  while( SQLITE_ROW == db_step(&qYears) ){
    const char *zT = db_column_text(&qYears, 0);
    if( i++ ){
      cgi_printf(" ");
    }
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
    Stmt stWeek = empty_Stmt;
    int rowCount = 0;
    int total = 0;
    Blob header = empty_blob;
    blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
                 "of %h", stats_report_label_for_type(),
                 zYear);
    blob_appendf(&sql,
                 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
                 "count(*) AS n "
                 "FROM v_reports "
                 "WHERE %Q=substr(date(mtime),1,4) "
                 "AND mtime < current_timestamp ",
                 zYear);
    if(zUserName&&*zUserName){
      blob_appendf(&sql, " AND user=%Q ", zUserName);
      blob_appendf(&header," for user %h", zUserName);
    }
    blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC");
    cgi_printf("<h1>%h</h1>", blob_str(&header));
    blob_reset(&header);
    cgi_printf("<table class='statistics-report-table-events' "
               "border='0' cellpadding='2' width='100%%' "
               "cellspacing='0' id='statsTable'>");
    cgi_printf("<thead><tr>"
               "<th>Week</th>"
               "<th>Events</th>"
               "<th width='90%%'><!-- relative commits graph --></th>"
               "</tr></thead>"
               "<tbody>");
    db_prepare(&stWeek, blob_str(&sql));
    blob_reset(&sql);
    while( SQLITE_ROW == db_step(&stWeek) ){
      const int nCount = db_column_int(&stWeek, 1);
      if(nCount>nMaxEvents){
        nMaxEvents = nCount;
      }
      ++iterations;







|
|






|


|











|







2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
    Stmt stWeek = empty_Stmt;
    int rowCount = 0;
    int total = 0;
    Blob header = empty_blob;
    blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
                 "of %h", stats_report_label_for_type(),
                 zYear);
    blob_append_sql(&sql,
                 "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
                 "count(*) AS n "
                 "FROM v_reports "
                 "WHERE %Q=substr(date(mtime),1,4) "
                 "AND mtime < current_timestamp ",
                 zYear);
    if(zUserName&&*zUserName){
      blob_append_sql(&sql, " AND user=%Q ", zUserName);
      blob_appendf(&header," for user %h", zUserName);
    }
    blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC");
    cgi_printf("<h1>%h</h1>", blob_str(&header));
    blob_reset(&header);
    cgi_printf("<table class='statistics-report-table-events' "
               "border='0' cellpadding='2' width='100%%' "
               "cellspacing='0' id='statsTable'>");
    cgi_printf("<thead><tr>"
               "<th>Week</th>"
               "<th>Events</th>"
               "<th width='90%%'><!-- relative commits graph --></th>"
               "</tr></thead>"
               "<tbody>");
    db_prepare(&stWeek, "%s", blob_sql_text(&sql));
    blob_reset(&sql);
    while( SQLITE_ROW == db_step(&stWeek) ){
      const int nCount = db_column_int(&stWeek, 1);
      if(nCount>nMaxEvents){
        nMaxEvents = nCount;
      }
      ++iterations;
Changes to src/tkt.c.
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
    db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
                  "VALUES(%Q, 0)", p->zTicketUuid);
    tktid = db_last_insert_rowid();
  }
  blob_zero(&sql1);
  blob_zero(&sql2);
  blob_zero(&sql3);
  blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
  if( haveTicketCTime ){
    blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
  }
  aUsed = fossil_malloc( nField );
  memset(aUsed, 0, nField);
  for(i=0; i<p->nField; i++){
    const char *zName = p->aField[i].zName;
    const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
    j = fieldId(zBaseName);
    if( j<0 ) continue;
    aUsed[j] = 1;
    if( aField[j].mUsed & USEDBY_TICKET ){
      if( zName[0]=='+' ){
        zName++;
        blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
                     zName, zName, p->aField[i].zValue);
      }else{
        blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
      }
    }
    if( aField[j].mUsed & USEDBY_TICKETCHNG ){
      blob_appendf(&sql2, ",%s", zName);
      blob_appendf(&sql3, ",%Q", p->aField[i].zValue);
    }
    if( rid>0 ){
      wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
    }
  }
  blob_appendf(&sql1, " WHERE tkt_id=%d", tktid);
  db_prepare(&q, "%s", blob_str(&sql1));
  db_bind_double(&q, ":mtime", p->rDate);
  db_step(&q);
  db_finalize(&q);
  blob_reset(&sql1);
  if( blob_size(&sql2)>0 || haveTicketChngRid ){
    int fromTkt = 0;
    if( haveTicketChngRid ){
      blob_append(&sql2, ",tkt_rid", -1);
      blob_appendf(&sql3, ",%d", rid);
    }
    for(i=0; i<nField; i++){
      if( aUsed[i]==0
       && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
      ){
        const char *z = aField[i].zName;
        if( z[0]=='+' ) z++;
        fromTkt = 1;
        blob_appendf(&sql2, ",%s", z);
        blob_appendf(&sql3, ",%s", z);
      }
    }
    if( fromTkt ){
      db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
                     "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",

                     blob_str(&sql2), tktid, blob_str(&sql3), tktid);
    }else{
      db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
                     "VALUES(%d,:mtime%s)",
                     blob_str(&sql2), tktid, blob_str(&sql3));
    }
    db_bind_double(&q, ":mtime", p->rDate);
    db_step(&q);
    db_finalize(&q);
  }
  blob_reset(&sql2);
  blob_reset(&sql3);







|

|












|


|



|
|





|
|








|








|
|





>
|



|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
    db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
                  "VALUES(%Q, 0)", p->zTicketUuid);
    tktid = db_last_insert_rowid();
  }
  blob_zero(&sql1);
  blob_zero(&sql2);
  blob_zero(&sql3);
  blob_append_sql(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
  if( haveTicketCTime ){
    blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
  }
  aUsed = fossil_malloc( nField );
  memset(aUsed, 0, nField);
  for(i=0; i<p->nField; i++){
    const char *zName = p->aField[i].zName;
    const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
    j = fieldId(zBaseName);
    if( j<0 ) continue;
    aUsed[j] = 1;
    if( aField[j].mUsed & USEDBY_TICKET ){
      if( zName[0]=='+' ){
        zName++;
        blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
                     zName, zName, p->aField[i].zValue);
      }else{
        blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue);
      }
    }
    if( aField[j].mUsed & USEDBY_TICKETCHNG ){
      blob_append_sql(&sql2, ",\"%w\"", zName);
      blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
    }
    if( rid>0 ){
      wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
    }
  }
  blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
  db_prepare(&q, "%s", blob_sql_text(&sql1));
  db_bind_double(&q, ":mtime", p->rDate);
  db_step(&q);
  db_finalize(&q);
  blob_reset(&sql1);
  if( blob_size(&sql2)>0 || haveTicketChngRid ){
    int fromTkt = 0;
    if( haveTicketChngRid ){
      blob_append(&sql2, ",tkt_rid", -1);
      blob_append_sql(&sql3, ",%d", rid);
    }
    for(i=0; i<nField; i++){
      if( aUsed[i]==0
       && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
      ){
        const char *z = aField[i].zName;
        if( z[0]=='+' ) z++;
        fromTkt = 1;
        blob_append_sql(&sql2, ",\"%w\"", z);
        blob_append_sql(&sql3, ",\"%w\"", z);
      }
    }
    if( fromTkt ){
      db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
                     "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
                     blob_sql_text(&sql2), tktid,
                     blob_sql_text(&sql3), tktid);
    }else{
      db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
                     "VALUES(%d,:mtime%s)",
                     blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
    }
    db_bind_double(&q, ":mtime", p->rDate);
    db_step(&q);
    db_finalize(&q);
  }
  blob_reset(&sql2);
  blob_reset(&sql3);
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
    "DROP TABLE IF EXISTS ticketchng;"
  );
  zSql = ticket_table_schema();
  if( separateConnection ){
    db_end_transaction(0);
    db_init_database(g.zRepositoryName, zSql, 0);
  }else{
    db_multi_exec("%s", zSql);
  }
}

/*
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
** available ticket artifacts.
*/







|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
    "DROP TABLE IF EXISTS ticketchng;"
  );
  zSql = ticket_table_schema();
  if( separateConnection ){
    db_end_transaction(0);
    db_init_database(g.zRepositoryName, zSql, 0);
  }else{
    db_multi_exec("%s", zSql/*safe-for-%s*/);
  }
}

/*
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
** available ticket artifacts.
*/
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
  if( rid==0 ){
    fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
  }
  if( needMod ){
    moderation_table_create();
    db_multi_exec(
      "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
      rid, zTktId
    );
  }else{
    db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
    db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
  }
  manifest_crosslink_begin();







|







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
  int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
  if( rid==0 ){
    fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
  }
  if( needMod ){
    moderation_table_create();
    db_multi_exec(
      "INSERT INTO modreq(objid, tktid) VALUES(%d,%Q)",
      rid, zTktId
    );
  }else{
    db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
    db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
  }
  manifest_crosslink_begin();
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
  style_submenu_element("Status", "Status",
    "%s/info/%s", g.zTop, zUuid);
  if( zType[0]=='c' ){
    zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
  }else{
    zTitle = mprintf("Timeline Of Ticket %h", zUuid);
  }
  style_header(zTitle);
  free(zTitle);

  sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
  canonical16(zGlobPattern, strlen(zGlobPattern));
  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
  if( tagid==0 ){
    @ No such ticket: %h(zUuid)
    style_footer();







|
<







854
855
856
857
858
859
860
861

862
863
864
865
866
867
868
  style_submenu_element("Status", "Status",
    "%s/info/%s", g.zTop, zUuid);
  if( zType[0]=='c' ){
    zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
  }else{
    zTitle = mprintf("Timeline Of Ticket %h", zUuid);
  }
  style_header("%z", zTitle);


  sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
  canonical16(zGlobPattern, strlen(zGlobPattern));
  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
  if( tagid==0 ){
    @ No such ticket: %h(zUuid)
    style_footer();
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
                  "   AND '%s' GLOB (target||'*')"
         "   UNION SELECT attachid FROM attachment"
                  " WHERE target=%Q) "
         "ORDER BY mtime DESC",
         timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
    );
  }
  db_prepare(&q, zSQL);
  free(zSQL);
  www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
                     0, 0, 0);
  db_finalize(&q);
  style_footer();
}

/*







|
<







887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
                  "   AND '%s' GLOB (target||'*')"
         "   UNION SELECT attachid FROM attachment"
                  " WHERE target=%Q) "
         "ORDER BY mtime DESC",
         timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
    );
  }
  db_prepare(&q, "%z", zSQL/*safe-for-%s*/);

  www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
                     0, 0, 0);
  db_finalize(&q);
  style_footer();
}

/*
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
  if( P("plaintext")!=0 ){
    style_submenu_element("Formatted", "Formatted",
                          "%R/tkthistory/%s", zUuid);
  }else{
    style_submenu_element("Plaintext", "Plaintext",
                          "%R/tkthistory/%s?plaintext", zUuid);
  }
  style_header(zTitle);
  free(zTitle);

  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
  if( tagid==0 ){
    @ No such ticket: %h(zUuid)
    style_footer();
    return;
  }







|
<







924
925
926
927
928
929
930
931

932
933
934
935
936
937
938
  if( P("plaintext")!=0 ){
    style_submenu_element("Formatted", "Formatted",
                          "%R/tkthistory/%s", zUuid);
  }else{
    style_submenu_element("Plaintext", "Plaintext",
                          "%R/tkthistory/%s?plaintext", zUuid);
  }
  style_header("%z", zTitle);


  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
  if( tagid==0 ){
    @ No such ticket: %h(zUuid)
    style_footer();
    return;
  }
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
        }else{
          eCmd = set;
        }
        if( g.argc==3 ){
          usage("set|change|history TICKETUUID");
        }
        zTktUuid = db_text(0,
          "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3]
        );
        if( !zTktUuid ){
          fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
        }
        i=4;
      }else if( strncmp(g.argv[2],"add",n)==0 ){
        eCmd = add;







|







1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
        }else{
          eCmd = set;
        }
        if( g.argc==3 ){
          usage("set|change|history TICKETUUID");
        }
        zTktUuid = db_text(0,
          "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%q*'", g.argv[3]
        );
        if( !zTktUuid ){
          fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
        }
        i=4;
      }else if( strncmp(g.argv[2],"add",n)==0 ){
        eCmd = add;
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
                  fossil_print("  Append to ");
            z++;
          }else{
            fossil_print("  Change ");
          }
          fossil_print("%h: ",z);
          if( blob_size(&val)>50 || contains_newline(&val)) {
                  fossil_print("\n    ",blob_str(&val));
                  comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
                }else{
                  fossil_print("%s\n",blob_str(&val));
                }
                blob_reset(&val);
              }
            }







|







1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
                  fossil_print("  Append to ");
            z++;
          }else{
            fossil_print("  Change ");
          }
          fossil_print("%h: ",z);
          if( blob_size(&val)>50 || contains_newline(&val)) {
                  fossil_print("\n    ");
                  comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
                }else{
                  fossil_print("%s\n",blob_str(&val));
                }
                blob_reset(&val);
              }
            }
Changes to src/translate.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** SYNOPSIS: 
**
** Input lines that begin with the "@" character are translated into
** either cgi_printf() statements or string literals and the
** translated code is written on standard output.
**
** The problem this program is attempt to solve is as follows:  When
** writing CGI programs in C, we typically want to output a lot of HTML
** text to standard output.  In pure C code, this involves doing a
** printf() with a big string containing all that text.  But we have
** to insert special codes (ex: \n and \") for many common characters,
** which interferes with the readability of the HTML.
**
** This tool allows us to put raw HTML, without the special codes, in
** the middle of a C program.  This program then translates the text
** into standard C by inserting all necessary backslashes and other
** punctuation.
**
** Enhancement #1:
**
** If the last non-whitespace character prior to the first "@" of a
** @-block is "=" or "," then the @-block is a string literal initializer 
** rather than text that is to be output via cgi_printf().  Render it
** as such.
**
** Enhancement #2:
**
** Comments of the form:  "/* @-comment: CC" cause CC to become a 
** comment character for the @-substitution.  Typical values for CC are
** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
** Lines of subsequent @-blocks that begin with CC are omitted from the
** output.
** 
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

/*







|




















|





|




|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** SYNOPSIS:
**
** Input lines that begin with the "@" character are translated into
** either cgi_printf() statements or string literals and the
** translated code is written on standard output.
**
** The problem this program is attempt to solve is as follows:  When
** writing CGI programs in C, we typically want to output a lot of HTML
** text to standard output.  In pure C code, this involves doing a
** printf() with a big string containing all that text.  But we have
** to insert special codes (ex: \n and \") for many common characters,
** which interferes with the readability of the HTML.
**
** This tool allows us to put raw HTML, without the special codes, in
** the middle of a C program.  This program then translates the text
** into standard C by inserting all necessary backslashes and other
** punctuation.
**
** Enhancement #1:
**
** If the last non-whitespace character prior to the first "@" of a
** @-block is "=" or "," then the @-block is a string literal initializer
** rather than text that is to be output via cgi_printf().  Render it
** as such.
**
** Enhancement #2:
**
** Comments of the form:  "/* @-comment: CC" cause CC to become a
** comment character for the @-substitution.  Typical values for CC are
** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
** Lines of subsequent @-blocks that begin with CC are omitted from the
** output.
**
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

/*
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
      i++;
      if( isspace(zLine[i]) ){ i++; }
      indent = i - 2;
      if( indent<0 ) indent = 0;
      omitline = 0;
      for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
        if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
           omitline = 1; break; 
        }
        if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
        zOut[j++] = zLine[i];
      }
      while( j>0 && isspace(zOut[j-1]) ){ j--; }
      zOut[j] = 0;
      if( j<=0 && omitline ){
        fprintf(out,"\n");
      }else{
        fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
      }
    }else{
      /* Otherwise (if the last non-whitespace was not '=') then generate
      ** a cgi_printf() statement whose format is the text following the '@'.
      ** Substrings of the form "%C(...)" (where C is any sequence of 
      ** characters other than \000 and '(') will put "%C" in the
      ** format and add the "(...)" as an argument to the cgi_printf call.
      */
      int indent;
      int nC;
      char c;
      i++;







|














|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
      i++;
      if( isspace(zLine[i]) ){ i++; }
      indent = i - 2;
      if( indent<0 ) indent = 0;
      omitline = 0;
      for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
        if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
           omitline = 1; break;
        }
        if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
        zOut[j++] = zLine[i];
      }
      while( j>0 && isspace(zOut[j-1]) ){ j--; }
      zOut[j] = 0;
      if( j<=0 && omitline ){
        fprintf(out,"\n");
      }else{
        fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
      }
    }else{
      /* Otherwise (if the last non-whitespace was not '=') then generate
      ** a cgi_printf() statement whose format is the text following the '@'.
      ** Substrings of the form "%C(...)" (where C is any sequence of
      ** characters other than \000 and '(') will put "%C" in the
      ** format and add the "(...)" as an argument to the cgi_printf call.
      */
      int indent;
      int nC;
      char c;
      i++;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
      zOut[j] = 0;
      if( !inPrint ){
        fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
        inPrint = 1;
      }else{
        fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
      }
    }      
  }
}

int main(int argc, char **argv){
  if( argc==2 ){
    char *arg;
    FILE *in = fopen(argv[1], "r");







|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
      zOut[j] = 0;
      if( !inPrint ){
        fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
        inPrint = 1;
      }else{
        fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
      }
    }
  }
}

int main(int argc, char **argv){
  if( argc==2 ){
    char *arg;
    FILE *in = fopen(argv[1], "r");
Changes to src/undo.c.
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
    "CREATE TEMP TABLE undo_vmerge_2 AS SELECT * FROM vmerge;"
    "DELETE FROM vmerge;"
    "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
    "DELETE FROM undo_vmerge;"
    "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
    "DROP TABLE undo_vmerge_2;"
  );
  if(db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='undo_stash'", zDb) ){

    if( redoFlag ){
      db_multi_exec(
        "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
        "DELETE FROM stashfile"
        " WHERE stashid NOT IN (SELECT stashid FROM stash);"
      );
    }else{







|
>







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    "CREATE TEMP TABLE undo_vmerge_2 AS SELECT * FROM vmerge;"
    "DELETE FROM vmerge;"
    "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
    "DELETE FROM undo_vmerge;"
    "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
    "DROP TABLE undo_vmerge_2;"
  );
  if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
               " WHERE name='undo_stash'", zDb) ){
    if( redoFlag ){
      db_multi_exec(
        "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
        "DELETE FROM stashfile"
        " WHERE stashid NOT IN (SELECT stashid FROM stash);"
      );
    }else{
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  static const char zSql[] =
    @ DROP TABLE IF EXISTS undo;
    @ DROP TABLE IF EXISTS undo_vfile;
    @ DROP TABLE IF EXISTS undo_vmerge;
    @ DROP TABLE IF EXISTS undo_stash;
    @ DROP TABLE IF EXISTS undo_stashfile;
    ;
  db_multi_exec(zSql);
  db_lset_int("undo_available", 0);
  db_lset_int("undo_checkout", 0);
}

/*
** The following variable stores the original command-line of the
** command that is a candidate to be undone.







|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  static const char zSql[] =
    @ DROP TABLE IF EXISTS undo;
    @ DROP TABLE IF EXISTS undo_vfile;
    @ DROP TABLE IF EXISTS undo_vmerge;
    @ DROP TABLE IF EXISTS undo_stash;
    @ DROP TABLE IF EXISTS undo_stashfile;
    ;
  db_multi_exec(zSql /*works-like:""*/);
  db_lset_int("undo_available", 0);
  db_lset_int("undo_checkout", 0);
}

/*
** The following variable stores the original command-line of the
** command that is a candidate to be undone.
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*
** Begin capturing a snapshot that can be undone.
*/
void undo_begin(void){
  int cid;
  const char *zDb = db_name("localdb");
  static const char zSql[] = 
    @ CREATE TABLE %s.undo(
    @   pathname TEXT UNIQUE,             -- Name of the file
    @   redoflag BOOLEAN,                 -- 0 for undoable.  1 for redoable
    @   existsflag BOOLEAN,               -- True if the file exists
    @   isExe BOOLEAN,                    -- True if the file is executable
    @   isLink BOOLEAN,                   -- True if the file is symlink
    @   content BLOB                      -- Saved content
    @ );
    @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
    @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
  ;
  if( undoDisable ) return;
  undo_reset();
  db_multi_exec(zSql, zDb, zDb, zDb);
  cid = db_lget_int("checkout", 0);
  db_lset_int("undo_checkout", cid);
  db_lset_int("undo_available", 1);
  db_lset("undo_cmdline", undoCmd);
  undoActive = 1;
}








|







|
|



|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/*
** Begin capturing a snapshot that can be undone.
*/
void undo_begin(void){
  int cid;
  const char *zDb = db_name("localdb");
  static const char zSql[] = 
    @ CREATE TABLE "%w".undo(
    @   pathname TEXT UNIQUE,             -- Name of the file
    @   redoflag BOOLEAN,                 -- 0 for undoable.  1 for redoable
    @   existsflag BOOLEAN,               -- True if the file exists
    @   isExe BOOLEAN,                    -- True if the file is executable
    @   isLink BOOLEAN,                   -- True if the file is symlink
    @   content BLOB                      -- Saved content
    @ );
    @ CREATE TABLE "%w".undo_vfile AS SELECT * FROM vfile;
    @ CREATE TABLE "%w".undo_vmerge AS SELECT * FROM vmerge;
  ;
  if( undoDisable ) return;
  undo_reset();
  db_multi_exec(zSql/*works-like:"%w,%w,%w"*/, zDb, zDb, zDb);
  cid = db_lget_int("checkout", 0);
  db_lset_int("undo_checkout", cid);
  db_lset_int("undo_available", 1);
  db_lset("undo_cmdline", undoCmd);
  undoActive = 1;
}

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

/*
** Make the current state of stashid undoable.
*/
void undo_save_stash(int stashid){
  const char *zDb = db_name("localdb");
  db_multi_exec(
    "CREATE TABLE IF NOT EXISTS %s.undo_stash"
    "  AS SELECT * FROM stash WHERE 0;"
    "INSERT INTO undo_stash"
    " SELECT * FROM stash WHERE stashid=%d;",
    zDb, stashid
  );
  db_multi_exec(
    "CREATE TABLE IF NOT EXISTS %s.undo_stashfile"
    "  AS SELECT * FROM stashfile WHERE 0;"
    "INSERT INTO undo_stashfile"
    " SELECT * FROM stashfile WHERE stashid=%d;",
    zDb, stashid
  );
}








|






|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

/*
** Make the current state of stashid undoable.
*/
void undo_save_stash(int stashid){
  const char *zDb = db_name("localdb");
  db_multi_exec(
    "CREATE TABLE IF NOT EXISTS \"%w\".undo_stash"
    "  AS SELECT * FROM stash WHERE 0;"
    "INSERT INTO undo_stash"
    " SELECT * FROM stash WHERE stashid=%d;",
    zDb, stashid
  );
  db_multi_exec(
    "CREATE TABLE IF NOT EXISTS \"%w\".undo_stashfile"
    "  AS SELECT * FROM stashfile WHERE 0;"
    "INSERT INTO undo_stashfile"
    " SELECT * FROM stashfile WHERE stashid=%d;",
    zDb, stashid
  );
}

Changes to src/update.c.
355
356
357
358
359
360
361
362

363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
    blob_zero(&sql);
    blob_append(&sql, "DELETE FROM fv WHERE ", -1);
    zSep = "";
    for(i=3; i<g.argc; i++){
      file_tree_name(g.argv[i], &treename, 1);
      if( file_wd_isdir(g.argv[i])==1 ){
        if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
          blob_appendf(&sql, "%sfn NOT GLOB '%b/*' ", zSep, &treename);

        }else{
          blob_reset(&sql);
          break;
        }
      }else{
        blob_appendf(&sql, "%sfn<>%B ", zSep, &treename);

      }
      zSep = "AND ";
      blob_reset(&treename);
    }
    db_multi_exec(blob_str(&sql));
    blob_reset(&sql);
  }

  /*
  ** Alter the content of the checkout so that it conforms with the
  ** target
  */







|
>





|
>




|







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    blob_zero(&sql);
    blob_append(&sql, "DELETE FROM fv WHERE ", -1);
    zSep = "";
    for(i=3; i<g.argc; i++){
      file_tree_name(g.argv[i], &treename, 1);
      if( file_wd_isdir(g.argv[i])==1 ){
        if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
          blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ", 
                         zSep /*safe-for-%s*/, blob_str(&treename));
        }else{
          blob_reset(&sql);
          break;
        }
      }else{
        blob_append_sql(&sql, "%sfn<>%Q ",
                        zSep /*safe-for-%s*/, blob_str(&treename));
      }
      zSep = "AND ";
      blob_reset(&treename);
    }
    db_multi_exec("%s", blob_sql_text(&sql));
    blob_reset(&sql);
  }

  /*
  ** Alter the content of the checkout so that it conforms with the
  ** target
  */
Changes to src/user.c.
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
                  "(SELECT rowid FROM accesslog ORDER BY rowid DESC"
                  " LIMIT -1 OFFSET 200)");
    cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
    return;
  }
  style_header("Access Log");
  blob_zero(&sql);
  blob_appendf(&sql,
    "SELECT uname, ipaddr, datetime(mtime%s), success"
    "  FROM accesslog", timeline_utc()
  );
  if( y==1 ){
    blob_append(&sql, "  WHERE success", -1);
  }else if( y==2 ){
    blob_append(&sql, "  WHERE NOT success", -1);
  }
  blob_appendf(&sql,"  ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
  if( skip ){
    style_submenu_element("Newer", "Newer entries",
              "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
              n, y);
  }
  rc = db_prepare_ignore_error(&q, blob_str(&sql));
  @ <center><table border="1" cellpadding="5">
  @ <tr><th width="33%%">Date</th><th width="34%%">User</th>
  @ <th width="33%%">IP Address</th></tr>
  while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    const char *zIP = db_column_text(&q, 1);
    const char *zDate = db_column_text(&q, 2);







|








|





|







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
                  "(SELECT rowid FROM accesslog ORDER BY rowid DESC"
                  " LIMIT -1 OFFSET 200)");
    cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
    return;
  }
  style_header("Access Log");
  blob_zero(&sql);
  blob_append_sql(&sql,
    "SELECT uname, ipaddr, datetime(mtime%s), success"
    "  FROM accesslog", timeline_utc()
  );
  if( y==1 ){
    blob_append(&sql, "  WHERE success", -1);
  }else if( y==2 ){
    blob_append(&sql, "  WHERE NOT success", -1);
  }
  blob_append_sql(&sql,"  ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
  if( skip ){
    style_submenu_element("Newer", "Newer entries",
              "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
              n, y);
  }
  rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
  @ <center><table border="1" cellpadding="5">
  @ <tr><th width="33%%">Date</th><th width="34%%">User</th>
  @ <th width="33%%">IP Address</th></tr>
  while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    const char *zIP = db_column_text(&q, 1);
    const char *zDate = db_column_text(&q, 2);
Changes to src/utf8.c.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "utf8.h"
#include <sqlite3.h>
#ifdef _WIN32
# include <windows.h>
#endif
#include "cygsup.h"

#ifdef _WIN32
/*
** Translate MBCS to UTF-8.  Return a pointer to the translated text.
** Call fossil_mbcs_free() to deallocate any memory used to store the
** returned pointer when done.
*/
char *fossil_mbcs_to_utf8(const char *zMbcs){
  extern char *sqlite3_win32_mbcs_to_utf8(const char*);







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "utf8.h"
#include <sqlite3.h>
#ifdef _WIN32
# include <windows.h>
#endif
#include "cygsup.h"

#if defined(_WIN32) || defined(__CYGWIN__)
/*
** Translate MBCS to UTF-8.  Return a pointer to the translated text.
** Call fossil_mbcs_free() to deallocate any memory used to store the
** returned pointer when done.
*/
char *fossil_mbcs_to_utf8(const char *zMbcs){
  extern char *sqlite3_win32_mbcs_to_utf8(const char*);
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323





324

325
326
327
328
329


330
331
332
333
334
335
336
** to the console.
*/
int fossil_utf8_to_console(const char *zUtf8, int nByte, int toStdErr){
#ifdef _WIN32
  int nChar, written = 0;
  wchar_t *zUnicode; /* Unicode version of zUtf8 */
  DWORD dummy;


  static int istty[2] = { -1, -1 };
  if( istty[toStdErr] == -1 ){
    istty[toStdErr] = _isatty(toStdErr + 1) != 0;
  }
  if( !istty[toStdErr] ){
    /* stdout/stderr is not a console. */
    return -1;
  }






  nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, nByte, NULL, 0);

  zUnicode = malloc( (nChar + 1) *sizeof(zUnicode[0]) );
  if( zUnicode==0 ){
    return 0;
  }
  nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, nByte, zUnicode, nChar);


  /* Split WriteConsoleW call into multiple chunks, if necessary. See:
   * <https://connect.microsoft.com/VisualStudio/feedback/details/635230> */
  while( written < nChar ){
    int size = nChar-written;
    if( size > 26000 ) size = 26000;
    WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE - toStdErr), zUnicode+written,
        size, &dummy, 0);







>










>
>
>
>
>
|
>




|
>
>







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
** to the console.
*/
int fossil_utf8_to_console(const char *zUtf8, int nByte, int toStdErr){
#ifdef _WIN32
  int nChar, written = 0;
  wchar_t *zUnicode; /* Unicode version of zUtf8 */
  DWORD dummy;
  Blob blob;

  static int istty[2] = { -1, -1 };
  if( istty[toStdErr] == -1 ){
    istty[toStdErr] = _isatty(toStdErr + 1) != 0;
  }
  if( !istty[toStdErr] ){
    /* stdout/stderr is not a console. */
    return -1;
  }

  /* If blob to be written to the Windows console is not
   * UTF-8, convert it to UTF-8 first.
   */
  blob_init(&blob, zUtf8, nByte); 
  blob_to_utf8_no_bom(&blob, 1);
  nChar = MultiByteToWideChar(CP_UTF8, 0, blob_buffer(&blob),
      blob_size(&blob), NULL, 0);
  zUnicode = malloc( (nChar + 1) *sizeof(zUnicode[0]) );
  if( zUnicode==0 ){
    return 0;
  }
  nChar = MultiByteToWideChar(CP_UTF8, 0, blob_buffer(&blob),
      blob_size(&blob), zUnicode, nChar);
  blob_reset(&blob);
  /* Split WriteConsoleW call into multiple chunks, if necessary. See:
   * <https://connect.microsoft.com/VisualStudio/feedback/details/635230> */
  while( written < nChar ){
    int size = nChar-written;
    if( size > 26000 ) size = 26000;
    WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE - toStdErr), zUnicode+written,
        size, &dummy, 0);
Changes to src/util.c.
76
77
78
79
80
81
82









83
84
85
86
87
88
89
  rc = _wsystem(zUnicode);
  fossil_unicode_free(zUnicode);
  free(zNewCmd);
#else
  /* On unix, evaluate the command directly.
  */
  if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);









  rc = system(zOrigCmd);
#endif
  return rc;
}

/*
** Like strcmp() except that it accepts NULL pointers.  NULL sorts before







>
>
>
>
>
>
>
>
>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  rc = _wsystem(zUnicode);
  fossil_unicode_free(zUnicode);
  free(zNewCmd);
#else
  /* On unix, evaluate the command directly.
  */
  if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);

  /* Unix systems should never shell-out while processing an HTTP request,
  ** either via CGI, SCGI, or direct HTTP.  The following assert verifies
  ** this.  And the following assert proves that Fossil is not vulnerable
  ** to the ShellShock or BashDoor bug.
  */
  assert( g.cgiOutput==0 );

  /* The regular system() call works to get a shell on unix */
  rc = system(zOrigCmd);
#endif
  return rc;
}

/*
** Like strcmp() except that it accepts NULL pointers.  NULL sorts before
Changes to src/vfile.c.
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
     "baseline",
     "merge",
     "original",
     "output",
  };
  int i, j, n;

  if( strglob("ci-comment-????????????.txt", zName) ) return 1;
  for(; zName[0]!=0; zName++){
    if( zName[0]=='/' && strglob("/ci-comment-????????????.txt", zName) ){
      return 1;
    }
    if( zName[0]!='-' ) continue;
    for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
      n = (int)strlen(azTemp[i]);
      if( memcmp(azTemp[i], zName+1, n) ) continue;
      if( zName[n+1]==0 ) return 1;







|

|







395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
     "baseline",
     "merge",
     "original",
     "output",
  };
  int i, j, n;

  if( sqlite3_strglob("ci-comment-????????????.txt", zName)==0 ) return 1;
  for(; zName[0]!=0; zName++){
    if( zName[0]=='/' && sqlite3_strglob("/ci-comment-????????????.txt", zName)==0 ){
      return 1;
    }
    if( zName[0]!='-' ) continue;
    for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
      n = (int)strlen(azTemp[i]);
      if( memcmp(azTemp[i], zName+1, n) ) continue;
      if( zName[n+1]==0 ) return 1;
Changes to src/wiki.c.
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
    }
    if( g.perm.Hyperlink ){
      style_submenu_element("History", "History", "%s/whistory?name=%T",
           g.zTop, zPageName);
    }
  }
  style_set_current_page("%T?name=%T", g.zPath, zPageName);
  style_header(zPageName);
  blob_init(&wiki, zBody, -1);
  wiki_render_by_mimetype(&wiki, zMimetype);
  blob_reset(&wiki);
  attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
  manifest_destroy(pWiki);
  style_footer();
}







|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
    }
    if( g.perm.Hyperlink ){
      style_submenu_element("History", "History", "%s/whistory?name=%T",
           g.zTop, zPageName);
    }
  }
  style_set_current_page("%T?name=%T", g.zPath, zPageName);
  style_header("%s", zPageName);
  blob_init(&wiki, zBody, -1);
  wiki_render_by_mimetype(&wiki, zMimetype);
  blob_reset(&wiki);
  attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
  manifest_destroy(pWiki);
  style_footer();
}
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
    Blob cksum;
    Blob body;
    Blob wiki;
    Manifest *pWiki = 0;

    blob_zero(&body);
    if( isSandbox ){
      blob_appendf(&body, db_get("sandbox",""));
      appendRemark(&body, zMimetype);
      db_set("sandbox", blob_str(&body), 0);
    }else{
      login_verify_csrf_secret();
      pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
      if( pWiki ){
        blob_append(&body, pWiki->zWiki, -1);







|







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
    Blob cksum;
    Blob body;
    Blob wiki;
    Manifest *pWiki = 0;

    blob_zero(&body);
    if( isSandbox ){
      blob_append(&body, db_get("sandbox",""), -1);
      appendRemark(&body, zMimetype);
      db_set("sandbox", blob_str(&body), 0);
    }else{
      login_verify_csrf_secret();
      pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
      if( pWiki ){
        blob_append(&body, pWiki->zWiki, -1);
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
** WEBPAGE: whistory
** URL: /whistory?name=PAGENAME
**
** Show the complete change history for a single wiki page.
*/
void whistory_page(void){
  Stmt q;
  char *zTitle;
  char *zSQL;
  const char *zPageName;
  login_check_credentials();
  if( !g.perm.Hyperlink ){ login_needed(); return; }
  zPageName = PD("name","");
  zTitle = mprintf("History Of %s", zPageName);
  style_header(zTitle);
  free(zTitle);

  zSQL = mprintf("%s AND event.objid IN "
                 "  (SELECT rid FROM tagxref WHERE tagid="
                       "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
                 "   UNION SELECT attachid FROM attachment"
                          " WHERE target=%Q)"
                 "ORDER BY mtime DESC",
                 timeline_query_for_www(), zPageName, zPageName);
  db_prepare(&q, zSQL);
  free(zSQL);
  zWikiPageName = zPageName;
  www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
  db_finalize(&q);
  style_footer();
}

/*
** WEBPAGE: wdiff
** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
**
** Show the difference between two wiki pages.
*/
void wdiff_page(void){
  char *zTitle;
  int rid1, rid2;
  const char *zPageName;
  Manifest *pW1, *pW2 = 0;
  Blob w1, w2, d;
  u64 diffFlags;

  login_check_credentials();
  rid1 = atoi(PD("a","0"));
  if( !g.perm.Hyperlink ){ login_needed(); return; }
  if( rid1==0 ) fossil_redirect_home();
  rid2 = atoi(PD("b","0"));
  zPageName = PD("name","");
  zTitle = mprintf("Changes To %s", zPageName);
  style_header(zTitle);
  free(zTitle);

  if( rid2==0 ){
    rid2 = db_int(0,
      "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
                        "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
      " WHERE event.mtime<(SELECT mtime FROM event WHERE objid=%d)"
      " ORDER BY event.mtime DESC LIMIT 1",







<
<




|
<
<

|






<
<













<












|
<
<







744
745
746
747
748
749
750


751
752
753
754
755


756
757
758
759
760
761
762
763


764
765
766
767
768
769
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784
785
786
787
788
789


790
791
792
793
794
795
796
** WEBPAGE: whistory
** URL: /whistory?name=PAGENAME
**
** Show the complete change history for a single wiki page.
*/
void whistory_page(void){
  Stmt q;


  const char *zPageName;
  login_check_credentials();
  if( !g.perm.Hyperlink ){ login_needed(); return; }
  zPageName = PD("name","");
  style_header("History Of %s", zPageName);



  db_prepare(&q, "%s AND event.objid IN "
                 "  (SELECT rid FROM tagxref WHERE tagid="
                       "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
                 "   UNION SELECT attachid FROM attachment"
                          " WHERE target=%Q)"
                 "ORDER BY mtime DESC",
                 timeline_query_for_www(), zPageName, zPageName);


  zWikiPageName = zPageName;
  www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
  db_finalize(&q);
  style_footer();
}

/*
** WEBPAGE: wdiff
** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
**
** Show the difference between two wiki pages.
*/
void wdiff_page(void){

  int rid1, rid2;
  const char *zPageName;
  Manifest *pW1, *pW2 = 0;
  Blob w1, w2, d;
  u64 diffFlags;

  login_check_credentials();
  rid1 = atoi(PD("a","0"));
  if( !g.perm.Hyperlink ){ login_needed(); return; }
  if( rid1==0 ) fossil_redirect_home();
  rid2 = atoi(PD("b","0"));
  zPageName = PD("name","");
  style_header("Changes To %s", zPageName);



  if( rid2==0 ){
    rid2 = db_int(0,
      "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
                        "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
      " WHERE event.mtime<(SELECT mtime FROM event WHERE objid=%d)"
      " ORDER BY event.mtime DESC LIMIT 1",
Changes to src/wikiformat.c.
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
/*
** Begin a new paragraph if that something that is needed.
*/
static void startAutoParagraph(Renderer *p){
  if( p->wantAutoParagraph==0 ) return;
  if( p->state & WIKI_LINKSONLY ) return;
  if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
  blob_appendf(p->pOut, "<p>", -1);
  p->wantAutoParagraph = 0;
  p->inAutoParagraph = 1;
}

/*
** End a paragraph if we are in one.
*/







|







1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
/*
** Begin a new paragraph if that something that is needed.
*/
static void startAutoParagraph(Renderer *p){
  if( p->wantAutoParagraph==0 ) return;
  if( p->state & WIKI_LINKSONLY ) return;
  if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
  blob_append(p->pOut, "<p>", -1);
  p->wantAutoParagraph = 0;
  p->inAutoParagraph = 1;
}

/*
** End a paragraph if we are in one.
*/
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
  memcpy(zUpper, zLower, n+1);
  zUpper[n-1]++;
  if( once ){
    const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
    db_static_prepare(&q,
      "SELECT %s FROM ticket "
      " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
      zClosedExpr
    );
    once = 0;
  }
  db_bind_text(&q, ":lwr", zLower);
  db_bind_text(&q, ":upr", zUpper);
  if( db_step(&q)==SQLITE_ROW ){
    rc = 1;







|







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
  memcpy(zUpper, zLower, n+1);
  zUpper[n-1]++;
  if( once ){
    const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
    db_static_prepare(&q,
      "SELECT %s FROM ticket "
      " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
      zClosedExpr /*safe-for-%s*/
    );
    once = 0;
  }
  db_bind_text(&q, ":lwr", zLower);
  db_bind_text(&q, ":upr", zUpper);
  if( db_step(&q)==SQLITE_ROW ){
    rc = 1;
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
          zTerm = "]";
        }
      }
    }else if( !in_this_repo(zTarget) ){
      if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
        zTerm = "";
      }else{
        blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget);
        zTerm = "]</span>";
      }
    }else if( g.perm.Hyperlink ){
      blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
      zTerm = "]</a>";
    }
  }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'







|







1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
          zTerm = "]";
        }
      }
    }else if( !in_this_repo(zTarget) ){
      if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
        zTerm = "";
      }else{
        blob_appendf(p->pOut, "<span class=\"brokenlink\">[");
        zTerm = "]</span>";
      }
    }else if( g.perm.Hyperlink ){
      blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
      zTerm = "]</a>";
    }
  }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
          blob_append(p->pOut, " &nbsp;&nbsp; ", -1);
        }else{
          if( p->wikiList ){
            popStackToTag(p, p->wikiList);
            p->wikiList = 0;
          }
          endAutoParagraph(p);
          blob_appendf(p->pOut, "\n\n", 1);
          p->wantAutoParagraph = 1;
        }
        p->state |= AT_PARAGRAPH|AT_NEWLINE;
        break;
      }
      case TOKEN_NEWLINE: {
        blob_append(p->pOut, "\n", 1);







|







1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
          blob_append(p->pOut, " &nbsp;&nbsp; ", -1);
        }else{
          if( p->wikiList ){
            popStackToTag(p, p->wikiList);
            p->wikiList = 0;
          }
          endAutoParagraph(p);
          blob_append(p->pOut, "\n\n", 1);
          p->wantAutoParagraph = 1;
        }
        p->state |= AT_PARAGRAPH|AT_NEWLINE;
        break;
      }
      case TOKEN_NEWLINE: {
        blob_append(p->pOut, "\n", 1);
Changes to src/winhttp.c.
56
57
58
59
60
61
62











63
64
65
66
67
68
69
        return atoi(&zHdr[17]);
      }
    }
    zHdr++;
  }
  return 0;
}












/*
** Process a single incoming HTTP request.
*/
static void win32_http_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
  FILE *in = 0, *out = 0;







>
>
>
>
>
>
>
>
>
>
>







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
        return atoi(&zHdr[17]);
      }
    }
    zHdr++;
  }
  return 0;
}

/*
** Issue a fatal error.
*/
static NORETURN void winhttp_fatal(
  const char *zOp,
  const char *zService,
  const char *zErr
){
  fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
}

/*
** Process a single incoming HTTP request.
*/
static void win32_http_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
  FILE *in = 0, *out = 0;
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    fossil_fatal("unable to get path to the temporary directory.");
  }
  zTempPrefix = mprintf("%sfossil_server_P%d_",
                        fossil_unicode_to_utf8(zTmpPath), iPort);
  fossil_print("Listening for %s requests on TCP port %d\n",
               (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
  if( zBrowser ){
    zBrowser = mprintf(zBrowser, iPort);
    fossil_print("Launch webbrowser: %s\n", zBrowser);
    fossil_system(zBrowser);
  }
  fossil_print("Type Ctrl-C to stop the HTTP server\n");
  /* Set the service status to running and pass the listener socket to the
  ** service handling procedures. */
  win32_http_service_running(s);







|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
    fossil_fatal("unable to get path to the temporary directory.");
  }
  zTempPrefix = mprintf("%sfossil_server_P%d_",
                        fossil_unicode_to_utf8(zTmpPath), iPort);
  fossil_print("Listening for %s requests on TCP port %d\n",
               (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
  if( zBrowser ){
    zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
    fossil_print("Launch webbrowser: %s\n", zBrowser);
    fossil_system(zBrowser);
  }
  fossil_print("Type Ctrl-C to stop the HTTP server\n");
  /* Set the service status to running and pass the listener socket to the
  ** service handling procedures. */
  win32_http_service_running(s);
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
  n = strlen(zMethod);

  if( strncmp(zMethod, "create", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_DESCRIPTIONW
      svcDescr = {L"Fossil - Distributed Software Configuration Management"};
    char *zErrFmt = "unable to create service '%s': %s";
    DWORD dwStartType = SERVICE_DEMAND_START;
    const char *zDisplay    = find_option("display", "D", 1);
    const char *zStart      = find_option("start", "S", 1);
    const char *zUsername   = find_option("username", "U", 1);
    const char *zPassword   = find_option("password", "W", 1);
    const char *zPort       = find_option("port", "P", 1);
    const char *zNotFound   = find_option("notfound", 0, 1);







<







688
689
690
691
692
693
694

695
696
697
698
699
700
701
  n = strlen(zMethod);

  if( strncmp(zMethod, "create", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_DESCRIPTIONW
      svcDescr = {L"Fossil - Distributed Software Configuration Management"};

    DWORD dwStartType = SERVICE_DEMAND_START;
    const char *zDisplay    = find_option("display", "D", 1);
    const char *zStart      = find_option("start", "S", 1);
    const char *zUsername   = find_option("username", "U", 1);
    const char *zPassword   = find_option("password", "W", 1);
    const char *zPort       = find_option("port", "P", 1);
    const char *zNotFound   = find_option("notfound", 0, 1);
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
    }
    if( zStart ){
      if( strncmp(zStart, "auto", strlen(zStart))==0 ){
        dwStartType = SERVICE_AUTO_START;
      }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
        dwStartType = SERVICE_DEMAND_START;
      }else{
        fossil_fatal(zErrFmt, zSvcName,
                     "specify 'auto' or 'manual' for the '-S|--start' option");
      }
    }
    /* Process options for Fossil running as server. */
    if( zPort && (atoi(zPort)<=0) ){
      fossil_fatal(zErrFmt, zSvcName,
                   "port number must be in the range 1 - 65535.");
    }
    if( !zRepository ){
      db_must_be_within_tree();
    }else if( file_isdir(zRepository)==1 ){
      g.zRepositoryName = mprintf("%s", zRepository);
      file_simplify_name(g.zRepositoryName, -1, 0);







|





|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
    }
    if( zStart ){
      if( strncmp(zStart, "auto", strlen(zStart))==0 ){
        dwStartType = SERVICE_AUTO_START;
      }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
        dwStartType = SERVICE_DEMAND_START;
      }else{
        winhttp_fatal("create", zSvcName,
                     "specify 'auto' or 'manual' for the '-S|--start' option");
      }
    }
    /* Process options for Fossil running as server. */
    if( zPort && (atoi(zPort)<=0) ){
      winhttp_fatal("create", zSvcName,
                   "port number must be in the range 1 - 65535.");
    }
    if( !zRepository ){
      db_must_be_within_tree();
    }else if( file_isdir(zRepository)==1 ){
      g.zRepositoryName = mprintf("%s", zRepository);
      file_simplify_name(g.zRepositoryName, -1, 0);
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    if( useSCGI ) blob_appendf(&binPath, " --scgi");
    if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound);
    if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
    if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
    blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
    /* Create the service. */
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = CreateServiceW(
             hScm,                                    /* Handle to the SCM */
             fossil_utf8_to_unicode(zSvcName),        /* Name of the service */
             fossil_utf8_to_unicode(zDisplay),        /* Display name */
             SERVICE_ALL_ACCESS,                      /* Desired access */
             SERVICE_WIN32_OWN_PROCESS,               /* Service type */
             dwStartType,                             /* Start type */
             SERVICE_ERROR_NORMAL,                    /* Error control */
             fossil_utf8_to_unicode(blob_str(&binPath)), /* Binary path */
             NULL,                                    /* Load ordering group */
             NULL,                                    /* Tag value */
             NULL,                                    /* Service dependencies */
             zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
             fossil_utf8_to_unicode(zPassword)        /* Account password */
           );
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Set the service description. */
    ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
    fossil_print("Service '%s' successfully created.\n", zSvcName);
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "delete", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    char *zErrFmt = "unable to delete service '%s': %s";

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for delete method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
                        SERVICE_ALL_ACCESS);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_STOPPED ){
      fossil_print("Stopping service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
        if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
          fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_STOPPED ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
      fossil_print("\nService '%s' stopped.\n", zSvcName);
    }
    if( !DeleteService(hSvc) ){
      if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
        fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
      }else{
        fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
      }
    }else{
      fossil_print("Service '%s' successfully deleted.\n", zSvcName);
    }
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "show", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    LPQUERY_SERVICE_CONFIGW pSvcConfig;
    LPSERVICE_DESCRIPTIONW pSvcDescr;
    BOOL bStatus;
    DWORD nRequired;
    const char *zErrFmt = "unable to show service '%s': %s";
    static const char *const zSvcTypes[] = {
      "Driver service",
      "File system driver service",
      "Service runs in its own process",
      "Service shares a process with other services",
      "Service can interact with the desktop"
    };







|















|










<








|


|





|













|















<







751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831

832
833
834
835
836
837
838
    if( useSCGI ) blob_appendf(&binPath, " --scgi");
    if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound);
    if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
    if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
    blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
    /* Create the service. */
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
    hSvc = CreateServiceW(
             hScm,                                    /* Handle to the SCM */
             fossil_utf8_to_unicode(zSvcName),        /* Name of the service */
             fossil_utf8_to_unicode(zDisplay),        /* Display name */
             SERVICE_ALL_ACCESS,                      /* Desired access */
             SERVICE_WIN32_OWN_PROCESS,               /* Service type */
             dwStartType,                             /* Start type */
             SERVICE_ERROR_NORMAL,                    /* Error control */
             fossil_utf8_to_unicode(blob_str(&binPath)), /* Binary path */
             NULL,                                    /* Load ordering group */
             NULL,                                    /* Tag value */
             NULL,                                    /* Service dependencies */
             zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
             fossil_utf8_to_unicode(zPassword)        /* Account password */
           );
    if( !hSvc ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
    /* Set the service description. */
    ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
    fossil_print("Service '%s' successfully created.\n", zSvcName);
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "delete", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;


    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for delete method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
                        SERVICE_ALL_ACCESS);
    if( !hSvc ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_STOPPED ){
      fossil_print("Stopping service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
        if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
          winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_STOPPED ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
      fossil_print("\nService '%s' stopped.\n", zSvcName);
    }
    if( !DeleteService(hSvc) ){
      if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
        fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
      }else{
        winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
      }
    }else{
      fossil_print("Service '%s' successfully deleted.\n", zSvcName);
    }
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "show", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    LPQUERY_SERVICE_CONFIGW pSvcConfig;
    LPSERVICE_DESCRIPTIONW pSvcDescr;
    BOOL bStatus;
    DWORD nRequired;

    static const char *const zSvcTypes[] = {
      "Driver service",
      "File system driver service",
      "Service runs in its own process",
      "Service shares a process with other services",
      "Service can interact with the desktop"
    };
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for show method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Get the service configuration */
    bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
    if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
      fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    }
    pSvcConfig = fossil_malloc(nRequired);
    bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
    if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Translate the service type */
    switch( pSvcConfig->dwServiceType ){
      case SERVICE_KERNEL_DRIVER:       zSvcType = zSvcTypes[0]; break;
      case SERVICE_FILE_SYSTEM_DRIVER:  zSvcType = zSvcTypes[1]; break;
      case SERVICE_WIN32_OWN_PROCESS:   zSvcType = zSvcTypes[2]; break;
      case SERVICE_WIN32_SHARE_PROCESS: zSvcType = zSvcTypes[3]; break;
      case SERVICE_INTERACTIVE_PROCESS: zSvcType = zSvcTypes[4]; break;
    }
    /* Translate the service start type */
    switch( pSvcConfig->dwStartType ){
      case SERVICE_BOOT_START:    zSvcStartType = zSvcStartTypes[0]; break;
      case SERVICE_SYSTEM_START:  zSvcStartType = zSvcStartTypes[1]; break;
      case SERVICE_AUTO_START:    zSvcStartType = zSvcStartTypes[2]; break;
      case SERVICE_DEMAND_START:  zSvcStartType = zSvcStartTypes[3]; break;
      case SERVICE_DISABLED:      zSvcStartType = zSvcStartTypes[4]; break;
    }
    /* Get the service description. */
    bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
                                  NULL, 0, &nRequired);
    if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
      fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    }
    pSvcDescr = fossil_malloc(nRequired);
    bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
                                  (LPBYTE)pSvcDescr, nRequired, &nRequired);
    if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Retrieves the current status of the specified service. */
    bStatus = QueryServiceStatus(hSvc, &sstat);
    if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Translate the current state. */
    switch( sstat.dwCurrentState ){
      case SERVICE_STOPPED:          zSvcState = zSvcStates[0]; break;
      case SERVICE_START_PENDING:    zSvcState = zSvcStates[1]; break;
      case SERVICE_STOP_PENDING:     zSvcState = zSvcStates[2]; break;
      case SERVICE_RUNNING:          zSvcState = zSvcStates[3]; break;
      case SERVICE_CONTINUE_PENDING: zSvcState = zSvcStates[4]; break;







|

|



|



|




















|




|


|







854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for show method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
    if( !hScm ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
    if( !hSvc ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
    /* Get the service configuration */
    bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
    if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
      winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
    }
    pSvcConfig = fossil_malloc(nRequired);
    bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
    if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
    /* Translate the service type */
    switch( pSvcConfig->dwServiceType ){
      case SERVICE_KERNEL_DRIVER:       zSvcType = zSvcTypes[0]; break;
      case SERVICE_FILE_SYSTEM_DRIVER:  zSvcType = zSvcTypes[1]; break;
      case SERVICE_WIN32_OWN_PROCESS:   zSvcType = zSvcTypes[2]; break;
      case SERVICE_WIN32_SHARE_PROCESS: zSvcType = zSvcTypes[3]; break;
      case SERVICE_INTERACTIVE_PROCESS: zSvcType = zSvcTypes[4]; break;
    }
    /* Translate the service start type */
    switch( pSvcConfig->dwStartType ){
      case SERVICE_BOOT_START:    zSvcStartType = zSvcStartTypes[0]; break;
      case SERVICE_SYSTEM_START:  zSvcStartType = zSvcStartTypes[1]; break;
      case SERVICE_AUTO_START:    zSvcStartType = zSvcStartTypes[2]; break;
      case SERVICE_DEMAND_START:  zSvcStartType = zSvcStartTypes[3]; break;
      case SERVICE_DISABLED:      zSvcStartType = zSvcStartTypes[4]; break;
    }
    /* Get the service description. */
    bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
                                  NULL, 0, &nRequired);
    if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
      winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
    }
    pSvcDescr = fossil_malloc(nRequired);
    bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
                                  (LPBYTE)pSvcDescr, nRequired, &nRequired);
    if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
    /* Retrieves the current status of the specified service. */
    bStatus = QueryServiceStatus(hSvc, &sstat);
    if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
    /* Translate the current state. */
    switch( sstat.dwCurrentState ){
      case SERVICE_STOPPED:          zSvcState = zSvcStates[0]; break;
      case SERVICE_START_PENDING:    zSvcState = zSvcStates[1]; break;
      case SERVICE_STOP_PENDING:     zSvcState = zSvcStates[2]; break;
      case SERVICE_RUNNING:          zSvcState = zSvcStates[3]; break;
      case SERVICE_CONTINUE_PENDING: zSvcState = zSvcStates[4]; break;
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "start", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    char *zErrFmt = "unable to start service '%s': %s";

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for start method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
                        SERVICE_ALL_ACCESS);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_RUNNING ){
      fossil_print("Starting service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
        if( !StartServiceW(hSvc, 0, NULL) ){
          fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_RUNNING ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
      fossil_print("\nService '%s' started.\n", zSvcName);
    }else{
      fossil_print("Service '%s' is already started.\n", zSvcName);
    }
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "stop", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    char *zErrFmt = "unable to stop service '%s': %s";

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for stop method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
                        SERVICE_ALL_ACCESS);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_STOPPED ){
      fossil_print("Stopping service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
        if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
          fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_STOPPED ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }







<








|


|





|


















<








|


|





|







927
928
929
930
931
932
933

934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969

970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "start", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;


    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for start method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
                        SERVICE_ALL_ACCESS);
    if( !hSvc ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_RUNNING ){
      fossil_print("Starting service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
        if( !StartServiceW(hSvc, 0, NULL) ){
          winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_RUNNING ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
      fossil_print("\nService '%s' started.\n", zSvcName);
    }else{
      fossil_print("Service '%s' is already started.\n", zSvcName);
    }
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "stop", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;


    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("too many arguments for stop method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
                        SERVICE_ALL_ACCESS);
    if( !hSvc ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_STOPPED ){
      fossil_print("Stopping service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
        if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
          winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_STOPPED ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
Changes to src/xfer.c.
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  Th_AppendToList(pzUuidList, pnUuidList, blob_str(&hash), blob_size(&hash));
  blob_reset(&hash);
  if( rid==0 ){
    blob_appendf(&pXfer->err, "%s", g.zErrMsg);
    blob_reset(&content);
  }else{
    if( !isPriv ) content_make_public(rid);
    manifest_crosslink(rid, &content, MC_NONE);
  }
  assert( blob_is_reset(&content) );
  remote_has(rid);
}

/*
** The aToken[0..nToken-1] blob array is a parse of a "cfile" line







|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  Th_AppendToList(pzUuidList, pnUuidList, blob_str(&hash), blob_size(&hash));
  blob_reset(&hash);
  if( rid==0 ){
    blob_appendf(&pXfer->err, "%s", g.zErrMsg);
    blob_reset(&content);
  }else{
    if( !isPriv ) content_make_public(rid);
    manifest_crosslink(rid, &content, MC_NO_ERRORS);
  }
  assert( blob_is_reset(&content) );
  remote_has(rid);
}

/*
** The aToken[0..nToken-1] blob array is a parse of a "cfile" line
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  };
  int i;
  Blob src, delta;
  int size = 0;
  int srcId = 0;

  for(i=0; srcId==0 && i<count(azQuery); i++){
    srcId = db_int(0, azQuery[i], rid);
  }
  if( srcId>0
   && (pXfer->syncPrivate || !content_is_private(srcId))
   && content_get(srcId, &src)
  ){
    char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", srcId);
    blob_delta_create(&src, pContent, &delta);







|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  };
  int i;
  Blob src, delta;
  int size = 0;
  int srcId = 0;

  for(i=0; srcId==0 && i<count(azQuery); i++){
    srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid);
  }
  if( srcId>0
   && (pXfer->syncPrivate || !content_is_private(srcId))
   && content_get(srcId, &src)
  ){
    char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", srcId);
    blob_delta_create(&src, pContent, &delta);
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
  if( uuid_is_shunned(blob_str(pUuid)) ){
    blob_reset(&uuid);
    return;
  }
  if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
       pXfer->mxSend<=blob_size(pXfer->pOut) ){
    const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
    blob_appendf(pXfer->pOut, zFormat, pUuid);
    pXfer->nIGotSent++;
    blob_reset(&uuid);
    return;
  }
  if( nativeDelta ){
    size = send_delta_native(pXfer, rid, isPriv, pUuid);
    if( size ){







|







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
  if( uuid_is_shunned(blob_str(pUuid)) ){
    blob_reset(&uuid);
    return;
  }
  if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
       pXfer->mxSend<=blob_size(pXfer->pOut) ){
    const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
    blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid);
    pXfer->nIGotSent++;
    blob_reset(&uuid);
    return;
  }
  if( nativeDelta ){
    size = send_delta_native(pXfer, rid, isPriv, pUuid);
    if( size ){
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
    }
    blob_reset(&content);
  }
  remote_has(rid);
  blob_reset(&uuid);
#if 0
  if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
    blob_appendf(pXfer->pOut, "\n", 1);
  }
#endif
}

/*
** Send the file identified by rid as a compressed artifact.  Basically,
** send the content exactly as it appears in the BLOB table using







|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
    }
    blob_reset(&content);
  }
  remote_has(rid);
  blob_reset(&uuid);
#if 0
  if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
    blob_append(pXfer->pOut, "\n", 1);
  }
#endif
}

/*
** Send the file identified by rid as a compressed artifact.  Basically,
** send the content exactly as it appears in the BLOB table using
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
      pXfer->nDeltaSent++;
    }else{
      pXfer->nFileSent++;
    }
    blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
    blob_append(pXfer->pOut, zContent, szC);
    if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
      blob_appendf(pXfer->pOut, "\n", 1);
    }
    if( !isPrivate && srcIsPrivate ){
      blob_reset(&fullContent);
    }
  }
  db_reset(&q1);
}







|







512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
      pXfer->nDeltaSent++;
    }else{
      pXfer->nFileSent++;
    }
    blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
    blob_append(pXfer->pOut, zContent, szC);
    if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
      blob_append(pXfer->pOut, "\n", 1);
    }
    if( !isPrivate && srcIsPrivate ){
      blob_reset(&fullContent);
    }
  }
  db_reset(&q1);
}
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
        md5sum_blob(&cluster, &cksum);
        blob_appendf(&cluster, "Z %b\n", &cksum);
        blob_reset(&cksum);
        rid = content_put(&cluster);
        blob_reset(&cluster);
        nUncl -= nRow;
        nRow = 0;
        blob_appendf(&deleteWhere, ",%d", rid);
      }
    }
    db_finalize(&q);
    db_multi_exec(
      "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
      "   AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
      blob_str(&deleteWhere)
    );
    blob_reset(&deleteWhere);
    if( nRow>0 ){
      md5sum_blob(&cluster, &cksum);
      blob_appendf(&cluster, "Z %b\n", &cksum);
      blob_reset(&cksum);
      content_put(&cluster);







|






|







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
        md5sum_blob(&cluster, &cksum);
        blob_appendf(&cluster, "Z %b\n", &cksum);
        blob_reset(&cksum);
        rid = content_put(&cluster);
        blob_reset(&cluster);
        nUncl -= nRow;
        nRow = 0;
        blob_append_sql(&deleteWhere, ",%d", rid);
      }
    }
    db_finalize(&q);
    db_multi_exec(
      "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
      "   AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
      blob_sql_text(&deleteWhere)
    );
    blob_reset(&deleteWhere);
    if( nRow>0 ){
      md5sum_blob(&cluster, &cksum);
      blob_appendf(&cluster, "Z %b\n", &cksum);
      blob_reset(&cksum);
      content_put(&cluster);
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
1508
  if( syncFlags & SYNC_PUSH ){
    blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
    nCardSent++;
    if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
    if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
  }
  if( syncFlags & SYNC_VERBOSE ){

    fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
  }

  while( go ){
    int newPhantom = 0;
    char *zRandomness;
    db_begin_transaction();
    db_record_repository_filename(0);







>
|







1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
  if( syncFlags & SYNC_PUSH ){
    blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
    nCardSent++;
    if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
    if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
  }
  if( syncFlags & SYNC_VERBOSE ){
    fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/,
                 "", "Bytes", "Cards", "Artifacts", "Deltas");
  }

  while( go ){
    int newPhantom = 0;
    char *zRandomness;
    db_begin_transaction();
    db_record_repository_filename(0);
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603

1604
1605
1606
1607
1608
1609
1610
1611
      nErr++;
      go = 2;
      break;
    }

    /* Output current stats */
    if( syncFlags & SYNC_VERBOSE ){
      fossil_print(zValueFormat, "Sent:",
                   blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
                   xfer.nFileSent, xfer.nDeltaSent);
    }else{
      nRoundtrip++;
      nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;

      fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
    }
    nCardSent = 0;
    nCardRcvd = 0;
    xfer.nFileSent = 0;
    xfer.nDeltaSent = 0;
    xfer.nGimmeSent = 0;
    xfer.nIGotSent = 0;







|





>
|







1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
      nErr++;
      go = 2;
      break;
    }

    /* Output current stats */
    if( syncFlags & SYNC_VERBOSE ){
      fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
                   blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
                   xfer.nFileSent, xfer.nDeltaSent);
    }else{
      nRoundtrip++;
      nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
      fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
                   nRoundtrip, nArtifactSent, nArtifactRcvd);
    }
    nCardSent = 0;
    nCardRcvd = 0;
    xfer.nFileSent = 0;
    xfer.nDeltaSent = 0;
    xfer.nGimmeSent = 0;
    xfer.nIGotSent = 0;
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
      **
      ** If the "login failed" message is seen, clear the sync password prior
      ** to the next cycle.
      */
      if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
        char *zMsg = blob_terminate(&xfer.aToken[1]);
        defossilize(zMsg);
        if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){
          syncFlags &= ~SYNC_PUSH;
          zMsg = 0;
        }
        if( zMsg && zMsg[0] ){
          fossil_force_newline();
          fossil_print("Server says: %s\n", zMsg);
        }







|







1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
      **
      ** If the "login failed" message is seen, clear the sync password prior
      ** to the next cycle.
      */
      if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
        char *zMsg = blob_terminate(&xfer.aToken[1]);
        defossilize(zMsg);
        if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){
          syncFlags &= ~SYNC_PUSH;
          zMsg = 0;
        }
        if( zMsg && zMsg[0] ){
          fossil_force_newline();
          fossil_print("Server says: %s\n", zMsg);
        }
1858
1859
1860
1861
1862
1863
1864


1865
1866
1867
1868
1869
1870
1871
              go = 1;
              if( g.cgiOutput==0 ){
                g.url.flags |= URL_PROMPT_PW;
                g.url.flags &= ~URL_PROMPTED;
                url_prompt_for_password();
                url_remember();
              }


            }
          }else{
            blob_appendf(&xfer.err, "server says: %s\n", zMsg);
            nErr++;
          }
          break;
        }







>
>







1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
              go = 1;
              if( g.cgiOutput==0 ){
                g.url.flags |= URL_PROMPT_PW;
                g.url.flags &= ~URL_PROMPTED;
                url_prompt_for_password();
                url_remember();
              }
            }else{
              nErr++;
            }
          }else{
            blob_appendf(&xfer.err, "server says: %s\n", zMsg);
            nErr++;
          }
          break;
        }
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906

1907
1908
1909
1910
1911
1912
1913
1914
    if( (configRcvMask & (CONFIGSET_USER|CONFIGSET_TKT))!=0
     && (configRcvMask & CONFIGSET_OLDFORMAT)!=0
    ){
      configure_finalize_receive();
    }
    origConfigRcvMask = 0;
    if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
      fossil_print(zValueFormat, "Received:",
                   blob_size(&recv), nCardRcvd,
                   xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
    }else{

      fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
    }
    blob_reset(&recv);
    nCycle++;

    /* If we received one or more files on the previous exchange but
    ** there are still phantoms, then go another round.
    */







|



>
|







1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
    if( (configRcvMask & (CONFIGSET_USER|CONFIGSET_TKT))!=0
     && (configRcvMask & CONFIGSET_OLDFORMAT)!=0
    ){
      configure_finalize_receive();
    }
    origConfigRcvMask = 0;
    if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
      fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:",
                   blob_size(&recv), nCardRcvd,
                   xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
    }else{
      fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
                   nRoundtrip, nArtifactSent, nArtifactRcvd);
    }
    blob_reset(&recv);
    nCycle++;

    /* If we received one or more files on the previous exchange but
    ** there are still phantoms, then go another round.
    */
Changes to win/Makefile.PellesCGMake.
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# define commands for building the windows resource files
RESOURCE=fossil.res
RC=$(PellesCDir)\bin\porc.exe
RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)

# define the special utilities files, needed to generate
# the automatically generated source files
UTILS=translate.exe mkindex.exe makeheaders.exe
UTILS_OBJ=$(UTILS:.exe=.obj)
UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))

# define the SQLite files, which need special flags on compile
SQLITESRC=sqlite3.c
ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# define commands for building the windows resource files
RESOURCE=fossil.res
RC=$(PellesCDir)\bin\porc.exe
RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)

# define the special utilities files, needed to generate
# the automatically generated source files
UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
UTILS_OBJ=$(UTILS:.exe=.obj)
UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))

# define the SQLite files, which need special flags on compile
SQLITESRC=sqlite3.c
ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)

# main target file is the application
APPLICATION=fossil.exe

# define the standard make target
.PHONY:	default
default:	page_index.h headers $(APPLICATION)

# symbolic target to generate the source generate utils
.PHONY:	utils
utils:	$(UTILS)

# link utils
$(UTILS) version.exe:	%.exe:	%.obj







|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)

# main target file is the application
APPLICATION=fossil.exe

# define the standard make target
.PHONY:	default
default:	page_index.h builtin_data.h headers $(APPLICATION)

# symbolic target to generate the source generate utils
.PHONY:	utils
utils:	$(UTILS)

# link utils
$(UTILS) version.exe:	%.exe:	%.obj
137
138
139
140
141
142
143



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# generate the translated c-source files
$(TRANSLATEDSRC):	%_.c:	$(SRCDIR)%.c translate.exe
	translate.exe $< >$@

# generate the index source, containing all web references,..
page_index.h:	$(TRANSLATEDSRC) mkindex.exe
	mkindex.exe $(TRANSLATEDSRC) >$@




# extracting version info from manifest
VERSION.h:	version.exe ..\manifest.uuid ..\manifest ..\VERSION
	version.exe ..\manifest.uuid ..\manifest ..\VERSION  > $@

# generate the simplified headers
headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
	makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
	echo Done >$@

# compile C sources with relevant options

$(TRANSLATEDOBJ):	%_.obj:	%_.c %.h
	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"







>
>
>



|


|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# generate the translated c-source files
$(TRANSLATEDSRC):	%_.c:	$(SRCDIR)%.c translate.exe
	translate.exe $< >$@

# generate the index source, containing all web references,..
page_index.h:	$(TRANSLATEDSRC) mkindex.exe
	mkindex.exe $(TRANSLATEDSRC) >$@

builtin_data.h:	$(EXTRA_FILES) mkbuiltin.exe
	mkbuiltin.exe $(EXTRA_FILES) >$@

# extracting version info from manifest
VERSION.h:	version.exe ..\manifest.uuid ..\manifest ..\VERSION
	version.exe ..\manifest.uuid ..\manifest ..\VERSION  >$@

# generate the simplified headers
headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
	makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
	echo Done >$@

# compile C sources with relevant options

$(TRANSLATEDOBJ):	%_.obj:	%_.c %.h
	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
Changes to win/Makefile.dmc.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68



69



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91



92
93
94
95
96
97
98
99
100
101
102
103
104
105
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 


RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

all: $(APPNAME)

$(APPNAME) : translate$E mkindex$E headers  $(OBJ) $(OBJDIR)\link
	cd $(OBJDIR)

	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
	+echo add allrepo attach bag bisect blob branch browse cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
	+echo fossil >> $@
	+echo fossil >> $@
	+echo $(LIBS) >> $@
	+echo. >> $@
	+echo fossil >> $@

translate$E: $(SRCDIR)\translate.c
	$(BCC) -o$@ $**

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) -o$@ $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) -o$@ $**




version$E: $B\src\mkversion.c



	$(BCC) -o$@ $**

$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
	$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**

$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
	$(TCC) -o$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $**

$(OBJDIR)\th$O : $(SRCDIR)\th.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
	cp $@ $@

VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
	+$** > $@

page_index.h: mkindex$E $(SRC)
	+$** > $@




clean:
	-del $(OBJDIR)\*.obj
	-del *.obj *_.c *.h *.map

realclean:
	-del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E

$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h







|

|









|

>






|















>
>
>
|
>
>
>

















|




>
>
>






|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 


RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

all: $(APPNAME)

$(APPNAME) : translate$E mkindex$E codecheck1$E headers  $(OBJ) $(OBJDIR)\link
	cd $(OBJDIR)
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
	+echo add allrepo attach bag bisect blob branch browse builtin cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
	+echo fossil >> $@
	+echo fossil >> $@
	+echo $(LIBS) >> $@
	+echo. >> $@
	+echo fossil >> $@

translate$E: $(SRCDIR)\translate.c
	$(BCC) -o$@ $**

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) -o$@ $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) -o$@ $**

mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
	$(BCC) -o$@ $**

mkversion$E: $(SRCDIR)\mkversion.c
	$(BCC) -o$@ $**

codecheck1$E: $(SRCDIR)\codecheck1.c
	$(BCC) -o$@ $**

$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
	$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**

$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
	$(TCC) -o$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $**

$(OBJDIR)\th$O : $(SRCDIR)\th.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
	$(TCC) -o$@ -c $**

$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
	cp $@ $@

VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
	+$** > $@

page_index.h: mkindex$E $(SRC)
	+$** > $@

builtin_data.h:	mkbuiltin$E $(EXTRA_FILES)
	+$** > $@

clean:
	-del $(OBJDIR)\*.obj
	-del *.obj *_.c *.h *.map

realclean:
	-del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E

$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h
158
159
160
161
162
163
164






165
166
167
168
169
170
171
	+translate$E $** > $@

$(OBJDIR)\browse$O : browse_.c browse.h
	$(TCC) -o$@ -c browse_.c

browse_.c : $(SRCDIR)\browse.c
	+translate$E $** > $@







$(OBJDIR)\cache$O : cache_.c cache.h
	$(TCC) -o$@ -c cache_.c

cache_.c : $(SRCDIR)\cache.c
	+translate$E $** > $@








>
>
>
>
>
>







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
	+translate$E $** > $@

$(OBJDIR)\browse$O : browse_.c browse.h
	$(TCC) -o$@ -c browse_.c

browse_.c : $(SRCDIR)\browse.c
	+translate$E $** > $@

$(OBJDIR)\builtin$O : builtin_.c builtin.h
	$(TCC) -o$@ -c builtin_.c

builtin_.c : $(SRCDIR)\builtin.c
	+translate$E $** > $@

$(OBJDIR)\cache$O : cache_.c cache.h
	$(TCC) -o$@ -c cache_.c

cache_.c : $(SRCDIR)\cache.c
	+translate$E $** > $@

777
778
779
780
781
782
783
784
785
786

$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

zip_.c : $(SRCDIR)\zip.c
	+translate$E $** > $@

headers: makeheaders$E page_index.h VERSION.h
	 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cache_.c:cache.h captcha_.c:captcha.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 configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers







|
|

793
794
795
796
797
798
799
800
801
802

$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

zip_.c : $(SRCDIR)\zip.c
	+translate$E $** > $@

headers: makeheaders$E page_index.h builtin_data.h VERSION.h
	 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h cache_.c:cache.h captcha_.c:captcha.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 configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers
Changes to win/Makefile.mingw.
97
98
99
100
101
102
103




















104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib





















#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
#    Fossil source code directory and the target OpenSSL source directory.
#
OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i

#### Either the directory where the Tcl library is installed or the Tcl
#    source code directory resides (depending on the value of the macro
#    FOSSIL_TCL_SOURCE).  If this points to the Tcl install directory,
#    this directory must have "include" and "lib" sub-directories.  If
#    this points to the Tcl source code directory, this directory must
#    have "generic" and "win" sub-directories.  The recommended usage







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib

ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif

ifndef X64
SSLCONFIG = mingw
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else
SSLCONFIG = mingw64
ZLIBCONFIG = 
LIBTARGETS =
endif

ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
#    Fossil source code directory and the target OpenSSL source directory.
#
OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j

#### Either the directory where the Tcl library is installed or the Tcl
#    source code directory resides (depending on the value of the macro
#    FOSSIL_TCL_SOURCE).  If this points to the Tcl install directory,
#    this directory must have "include" and "lib" sub-directories.  If
#    this points to the Tcl source code directory, this directory must
#    have "generic" and "win" sub-directories.  The recommended usage
329
330
331
332
333
334
335

336
337
338
339
340
341
342
  $(SRCDIR)/allrepo.c \
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \

  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \







>







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
  $(SRCDIR)/allrepo.c \
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \
  $(SRCDIR)/builtin.c \
  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \
433
434
435
436
437
438
439



440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
  $(SRCDIR)/winfile.c \
  $(SRCDIR)/winhttp.c \
  $(SRCDIR)/wysiwyg.c \
  $(SRCDIR)/xfer.c \
  $(SRCDIR)/xfersetup.c \
  $(SRCDIR)/zip.c




TRANS_SRC = \
  $(OBJDIR)/add_.c \
  $(OBJDIR)/allrepo_.c \
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \

  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \







>
>
>









>







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  $(SRCDIR)/winfile.c \
  $(SRCDIR)/winhttp.c \
  $(SRCDIR)/wysiwyg.c \
  $(SRCDIR)/xfer.c \
  $(SRCDIR)/xfersetup.c \
  $(SRCDIR)/zip.c

EXTRA_FILES = \
  $(SRCDIR)/diff.tcl

TRANS_SRC = \
  $(OBJDIR)/add_.c \
  $(OBJDIR)/allrepo_.c \
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \
  $(OBJDIR)/builtin_.c \
  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \
555
556
557
558
559
560
561

562
563
564
565
566
567
568
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \

 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \







>







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \
 $(OBJDIR)/builtin.o \
 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681


682
683
684
685
686
687
688
689
690
691
692
693


694
695
696
697
698
699
700
 $(OBJDIR)/wysiwyg.o \
 $(OBJDIR)/xfer.o \
 $(OBJDIR)/xfersetup.o \
 $(OBJDIR)/zip.o

APPNAME    = fossil.exe
APPTARGETS =
LIBTARGETS =

#### If the USE_WINDOWS variable exists, it is assumed that we are building
#    inside of a Windows-style shell; otherwise, it is assumed that we are
#    building inside of a Unix-style shell.  Note that the "move" command is
#    broken when attempting to use it from the Windows shell via MinGW make
#    because the SHELL variable is only used for certain commands that are
#    recognized internally by make.
#
ifdef USE_WINDOWS
TRANSLATE   = $(subst /,\,$(OBJDIR)/translate.exe)
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
MKINDEX     = $(subst /,\,$(OBJDIR)/mkindex.exe)
VERSION     = $(subst /,\,$(OBJDIR)/version.exe)


CAT         = type
CP          = copy
GREP        = find
MV          = copy
RM          = del /Q
MKDIR       = -mkdir
RMDIR       = rmdir /S /Q
else
TRANSLATE   = $(OBJDIR)/translate.exe
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
MKINDEX     = $(OBJDIR)/mkindex.exe
VERSION     = $(OBJDIR)/version.exe


CAT         = cat
CP          = cp
GREP        = grep
MV          = mv
RM          = rm -f
MKDIR       = -mkdir -p
RMDIR       = rm -rf







<












|
>
>











|
>
>







687
688
689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
 $(OBJDIR)/wysiwyg.o \
 $(OBJDIR)/xfer.o \
 $(OBJDIR)/xfersetup.o \
 $(OBJDIR)/zip.o

APPNAME    = fossil.exe
APPTARGETS =


#### If the USE_WINDOWS variable exists, it is assumed that we are building
#    inside of a Windows-style shell; otherwise, it is assumed that we are
#    building inside of a Unix-style shell.  Note that the "move" command is
#    broken when attempting to use it from the Windows shell via MinGW make
#    because the SHELL variable is only used for certain commands that are
#    recognized internally by make.
#
ifdef USE_WINDOWS
TRANSLATE   = $(subst /,\,$(OBJDIR)/translate.exe)
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
MKINDEX     = $(subst /,\,$(OBJDIR)/mkindex.exe)
MKBUILTIN   = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
MKVERSION   = $(subst /,\,$(OBJDIR)/mkversion.exe)
CODECHECK1  = $(subst /,\,$(OBJDIR)/codecheck1.exe)
CAT         = type
CP          = copy
GREP        = find
MV          = copy
RM          = del /Q
MKDIR       = -mkdir
RMDIR       = rmdir /S /Q
else
TRANSLATE   = $(OBJDIR)/translate.exe
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
MKINDEX     = $(OBJDIR)/mkindex.exe
MKBUILTIN   = $(OBJDIR)/mkbuiltin.exe
MKVERSION   = $(OBJDIR)/mkversion.exe
CODECHECK1  = $(OBJDIR)/codecheck1.exe
CAT         = cat
CP          = cp
GREP        = grep
MV          = mv
RM          = rm -f
MKDIR       = -mkdir -p
RMDIR       = rm -rf
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743



744
745



746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
ifdef USE_WINDOWS
	$(MKDIR) $(subst /,\,$(OBJDIR))
else
	$(MKDIR) $(OBJDIR)
endif

$(TRANSLATE):	$(SRCDIR)/translate.c
	$(BCC) -o $(TRANSLATE) $(SRCDIR)/translate.c

$(MAKEHEADERS):	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c

$(MKINDEX):	$(SRCDIR)/mkindex.c
	$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c




$(VERSION): $(SRCDIR)/mkversion.c
	$(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c




# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
	$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h

# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
# to 1. If it is set to 1, then there is no need to build or link
# the sqlite3.o object. Instead, the system SQLite will be linked
# using -lsqlite3.
SQLITE3_OBJ.1 =
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o







|


|


|

>
>
>
|
|
>
>
>







|
|







758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
ifdef USE_WINDOWS
	$(MKDIR) $(subst /,\,$(OBJDIR))
else
	$(MKDIR) $(OBJDIR)
endif

$(TRANSLATE):	$(SRCDIR)/translate.c
	$(BCC) -o $@ $(SRCDIR)/translate.c

$(MAKEHEADERS):	$(SRCDIR)/makeheaders.c
	$(BCC) -o $@ $(SRCDIR)/makeheaders.c

$(MKINDEX):	$(SRCDIR)/mkindex.c
	$(BCC) -o $@ $(SRCDIR)/mkindex.c

$(MKBUILTIN):	$(SRCDIR)/mkbuiltin.c
	$(BCC) -o $@ $(SRCDIR)/mkbuiltin.c

$(MKVERSION): $(SRCDIR)/mkversion.c
	$(BCC) -o $@ $(SRCDIR)/mkversion.c

$(CODECHECK1):	$(SRCDIR)/codecheck1.c
	$(BCC) -o $@ $(SRCDIR)/codecheck1.c

# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
	$(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$@

# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
# to 1. If it is set to 1, then there is no need to build or link
# the sqlite3.o object. Instead, the system SQLite will be linked
# using -lsqlite3.
SQLITE3_OBJ.1 =
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o
776
777
778
779
780
781
782
783
784
785
786







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
 $(OBJDIR)/th.o \
 $(OBJDIR)/th_lang.o \
 $(OBJDIR)/th_tcl.o \
 $(OBJDIR)/cson_amalgamation.o


zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a

clean-zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean








ifndef FOSSIL_ENABLE_MINIZ
LIBTARGETS += zlib
endif

openssl:	$(LIBTARGETS)
ifndef FOSSIL_ENABLE_MINIZ
	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib mingw
else
	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) mingw
endif
	$(MAKE) -C $(OPENSSLLIBDIR) build_libs

clean-openssl:
	$(MAKE) -C $(OPENSSLLIBDIR) clean

tcl:
	cd $(TCLSRCDIR)/win;./configure
	$(MAKE) -C $(TCLSRCDIR)/win $(TCLTARGET)

clean-tcl:
	$(MAKE) -C $(TCLSRCDIR)/win distclean

APPTARGETS += $(LIBTARGETS)

ifdef FOSSIL_BUILD_SSL
APPTARGETS += openssl
endif

$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)

	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o

# 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:
	# noop








|



>
>
>
>
>
>
>






<
<
<
|
<


















|
>
|







811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834



835

836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
 $(OBJDIR)/th.o \
 $(OBJDIR)/th_lang.o \
 $(OBJDIR)/th_tcl.o \
 $(OBJDIR)/cson_amalgamation.o


zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) $(ZLIBCONFIG) -f win32/Makefile.gcc libz.a

clean-zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean

$(ZLIBDIR)/inffas86.o:
	$(TCC) -c -o $@ -DASMINF -I$(ZLIBDIR) -O3 $(ZLIBDIR)/contrib/inflate86/inffas86.c

$(ZLIBDIR)/match.o:
	$(TCC) -c -o $@ -DASMV $(ZLIBDIR)/contrib/asm686/match.S


ifndef FOSSIL_ENABLE_MINIZ
LIBTARGETS += zlib
endif

openssl:	$(LIBTARGETS)



	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)

	$(MAKE) -C $(OPENSSLLIBDIR) build_libs

clean-openssl:
	$(MAKE) -C $(OPENSSLLIBDIR) clean

tcl:
	cd $(TCLSRCDIR)/win;./configure
	$(MAKE) -C $(TCLSRCDIR)/win $(TCLTARGET)

clean-tcl:
	$(MAKE) -C $(TCLSRCDIR)/win distclean

APPTARGETS += $(LIBTARGETS)

ifdef FOSSIL_BUILD_SSL
APPTARGETS += openssl
endif

$(APPNAME):	$(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
	$(CODECHECK1) $(TRANS_SRC)
	$(TCC) -o $@ $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o

# 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:
	# noop

836
837
838
839
840
841
842



843
844
845
846
847
848
849
850
851

852
853
854
855
856
857
858

innosetup: $(OBJDIR) $(APPNAME)
	$(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)

$(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
	$(MKINDEX) $(TRANS_SRC) >$@




$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
	$(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
		$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
		$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
		$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
		$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
		$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
		$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
		$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \

		$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
		$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
		$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
		$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
		$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
		$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
		$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \







>
>
>
|








>







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901

innosetup: $(OBJDIR) $(APPNAME)
	$(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)

$(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
	$(MKINDEX) $(TRANS_SRC) >$@

$(OBJDIR)/builtin_data.h:	$(MKBUILTIN) $(EXTRA_FILES)
	$(MKBUILTIN) $(EXTRA_FILES) >$@

$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
	$(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
		$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
		$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
		$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
		$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
		$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
		$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
		$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
		$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
		$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
		$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
		$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
		$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
		$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
		$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
		$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027








1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
	echo Done >$(OBJDIR)/headers

$(OBJDIR)/headers: Makefile

Makefile:

$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c

$(OBJDIR)/add.o:	$(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c

$(OBJDIR)/add.h:	$(OBJDIR)/headers

$(OBJDIR)/allrepo_.c:	$(SRCDIR)/allrepo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/allrepo.c >$(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.o:	$(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.h:	$(OBJDIR)/headers

$(OBJDIR)/attach_.c:	$(SRCDIR)/attach.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/attach.c >$(OBJDIR)/attach_.c

$(OBJDIR)/attach.o:	$(OBJDIR)/attach_.c $(OBJDIR)/attach.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/attach.o -c $(OBJDIR)/attach_.c

$(OBJDIR)/attach.h:	$(OBJDIR)/headers

$(OBJDIR)/bag_.c:	$(SRCDIR)/bag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bag.c >$(OBJDIR)/bag_.c

$(OBJDIR)/bag.o:	$(OBJDIR)/bag_.c $(OBJDIR)/bag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c $(OBJDIR)/bag_.c

$(OBJDIR)/bag.h:	$(OBJDIR)/headers

$(OBJDIR)/bisect_.c:	$(SRCDIR)/bisect.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bisect.c >$(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.o:	$(OBJDIR)/bisect_.c $(OBJDIR)/bisect.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bisect.o -c $(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.h:	$(OBJDIR)/headers

$(OBJDIR)/blob_.c:	$(SRCDIR)/blob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/blob.c >$(OBJDIR)/blob_.c

$(OBJDIR)/blob.o:	$(OBJDIR)/blob_.c $(OBJDIR)/blob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c $(OBJDIR)/blob_.c

$(OBJDIR)/blob.h:	$(OBJDIR)/headers

$(OBJDIR)/branch_.c:	$(SRCDIR)/branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/branch.c >$(OBJDIR)/branch_.c

$(OBJDIR)/branch.o:	$(OBJDIR)/branch_.c $(OBJDIR)/branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c $(OBJDIR)/branch_.c

$(OBJDIR)/branch.h:	$(OBJDIR)/headers

$(OBJDIR)/browse_.c:	$(SRCDIR)/browse.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/browse.c >$(OBJDIR)/browse_.c

$(OBJDIR)/browse.o:	$(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c

$(OBJDIR)/browse.h:	$(OBJDIR)/headers









$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

$(OBJDIR)/cache.h:	$(OBJDIR)/headers

$(OBJDIR)/captcha_.c:	$(SRCDIR)/captcha.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/captcha.c >$(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.o:	$(OBJDIR)/captcha_.c $(OBJDIR)/captcha.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c $(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.h:	$(OBJDIR)/headers

$(OBJDIR)/cgi_.c:	$(SRCDIR)/cgi.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cgi.c >$(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.o:	$(OBJDIR)/cgi_.c $(OBJDIR)/cgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c $(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.h:	$(OBJDIR)/headers

$(OBJDIR)/checkin_.c:	$(SRCDIR)/checkin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkin.c >$(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.o:	$(OBJDIR)/checkin_.c $(OBJDIR)/checkin.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c $(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.h:	$(OBJDIR)/headers

$(OBJDIR)/checkout_.c:	$(SRCDIR)/checkout.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkout.c >$(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.o:	$(OBJDIR)/checkout_.c $(OBJDIR)/checkout.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c $(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.h:	$(OBJDIR)/headers

$(OBJDIR)/clearsign_.c:	$(SRCDIR)/clearsign.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clearsign.c >$(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.o:	$(OBJDIR)/clearsign_.c $(OBJDIR)/clearsign.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c $(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.h:	$(OBJDIR)/headers

$(OBJDIR)/clone_.c:	$(SRCDIR)/clone.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clone.c >$(OBJDIR)/clone_.c

$(OBJDIR)/clone.o:	$(OBJDIR)/clone_.c $(OBJDIR)/clone.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c $(OBJDIR)/clone_.c

$(OBJDIR)/clone.h:	$(OBJDIR)/headers

$(OBJDIR)/comformat_.c:	$(SRCDIR)/comformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/comformat.c >$(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.o:	$(OBJDIR)/comformat_.c $(OBJDIR)/comformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c $(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.h:	$(OBJDIR)/headers

$(OBJDIR)/configure_.c:	$(SRCDIR)/configure.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/configure.c >$(OBJDIR)/configure_.c

$(OBJDIR)/configure.o:	$(OBJDIR)/configure_.c $(OBJDIR)/configure.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c $(OBJDIR)/configure_.c

$(OBJDIR)/configure.h:	$(OBJDIR)/headers

$(OBJDIR)/content_.c:	$(SRCDIR)/content.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/content.c >$(OBJDIR)/content_.c

$(OBJDIR)/content.o:	$(OBJDIR)/content_.c $(OBJDIR)/content.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c $(OBJDIR)/content_.c

$(OBJDIR)/content.h:	$(OBJDIR)/headers

$(OBJDIR)/db_.c:	$(SRCDIR)/db.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/db.c >$(OBJDIR)/db_.c

$(OBJDIR)/db.o:	$(OBJDIR)/db_.c $(OBJDIR)/db.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c $(OBJDIR)/db_.c

$(OBJDIR)/db.h:	$(OBJDIR)/headers

$(OBJDIR)/delta_.c:	$(SRCDIR)/delta.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/delta.c >$(OBJDIR)/delta_.c

$(OBJDIR)/delta.o:	$(OBJDIR)/delta_.c $(OBJDIR)/delta.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c $(OBJDIR)/delta_.c

$(OBJDIR)/delta.h:	$(OBJDIR)/headers

$(OBJDIR)/deltacmd_.c:	$(SRCDIR)/deltacmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/deltacmd.c >$(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.o:	$(OBJDIR)/deltacmd_.c $(OBJDIR)/deltacmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c $(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.h:	$(OBJDIR)/headers

$(OBJDIR)/descendants_.c:	$(SRCDIR)/descendants.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/descendants.c >$(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.o:	$(OBJDIR)/descendants_.c $(OBJDIR)/descendants.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c $(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.h:	$(OBJDIR)/headers

$(OBJDIR)/diff_.c:	$(SRCDIR)/diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diff.c >$(OBJDIR)/diff_.c

$(OBJDIR)/diff.o:	$(OBJDIR)/diff_.c $(OBJDIR)/diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c $(OBJDIR)/diff_.c

$(OBJDIR)/diff.h:	$(OBJDIR)/headers

$(OBJDIR)/diffcmd_.c:	$(SRCDIR)/diffcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diffcmd.c >$(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.o:	$(OBJDIR)/diffcmd_.c $(OBJDIR)/diffcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c $(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/doc_.c:	$(SRCDIR)/doc.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/doc.c >$(OBJDIR)/doc_.c

$(OBJDIR)/doc.o:	$(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c

$(OBJDIR)/doc.h:	$(OBJDIR)/headers

$(OBJDIR)/encode_.c:	$(SRCDIR)/encode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/encode.c >$(OBJDIR)/encode_.c

$(OBJDIR)/encode.o:	$(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c

$(OBJDIR)/encode.h:	$(OBJDIR)/headers

$(OBJDIR)/event_.c:	$(SRCDIR)/event.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/event.c >$(OBJDIR)/event_.c

$(OBJDIR)/event.o:	$(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/event.o -c $(OBJDIR)/event_.c

$(OBJDIR)/event.h:	$(OBJDIR)/headers

$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/export.c >$(OBJDIR)/export_.c

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/file.c >$(OBJDIR)/file_.c

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

$(OBJDIR)/file.h:	$(OBJDIR)/headers

$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.h:	$(OBJDIR)/headers

$(OBJDIR)/glob_.c:	$(SRCDIR)/glob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/glob.c >$(OBJDIR)/glob_.c

$(OBJDIR)/glob.o:	$(OBJDIR)/glob_.c $(OBJDIR)/glob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/glob.o -c $(OBJDIR)/glob_.c

$(OBJDIR)/glob.h:	$(OBJDIR)/headers

$(OBJDIR)/graph_.c:	$(SRCDIR)/graph.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/graph.c >$(OBJDIR)/graph_.c

$(OBJDIR)/graph.o:	$(OBJDIR)/graph_.c $(OBJDIR)/graph.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c $(OBJDIR)/graph_.c

$(OBJDIR)/graph.h:	$(OBJDIR)/headers

$(OBJDIR)/gzip_.c:	$(SRCDIR)/gzip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/gzip.c >$(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.o:	$(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.h:	$(OBJDIR)/headers

$(OBJDIR)/http_.c:	$(SRCDIR)/http.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http.c >$(OBJDIR)/http_.c

$(OBJDIR)/http.o:	$(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c

$(OBJDIR)/http.h:	$(OBJDIR)/headers

$(OBJDIR)/http_socket_.c:	$(SRCDIR)/http_socket.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_socket.c >$(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.o:	$(OBJDIR)/http_socket_.c $(OBJDIR)/http_socket.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c $(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.h:	$(OBJDIR)/headers

$(OBJDIR)/http_ssl_.c:	$(SRCDIR)/http_ssl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_ssl.c >$(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.o:	$(OBJDIR)/http_ssl_.c $(OBJDIR)/http_ssl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_ssl.o -c $(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.h:	$(OBJDIR)/headers

$(OBJDIR)/http_transport_.c:	$(SRCDIR)/http_transport.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_transport.c >$(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.o:	$(OBJDIR)/http_transport_.c $(OBJDIR)/http_transport.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c $(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.h:	$(OBJDIR)/headers

$(OBJDIR)/import_.c:	$(SRCDIR)/import.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/import.c >$(OBJDIR)/import_.c

$(OBJDIR)/import.o:	$(OBJDIR)/import_.c $(OBJDIR)/import.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/import.o -c $(OBJDIR)/import_.c

$(OBJDIR)/import.h:	$(OBJDIR)/headers

$(OBJDIR)/info_.c:	$(SRCDIR)/info.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/info.c >$(OBJDIR)/info_.c

$(OBJDIR)/info.o:	$(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c

$(OBJDIR)/info.h:	$(OBJDIR)/headers

$(OBJDIR)/json_.c:	$(SRCDIR)/json.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json.c >$(OBJDIR)/json_.c

$(OBJDIR)/json.o:	$(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c

$(OBJDIR)/json.h:	$(OBJDIR)/headers

$(OBJDIR)/json_artifact_.c:	$(SRCDIR)/json_artifact.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.o:	$(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.h:	$(OBJDIR)/headers

$(OBJDIR)/json_branch_.c:	$(SRCDIR)/json_branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.o:	$(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.h:	$(OBJDIR)/headers

$(OBJDIR)/json_config_.c:	$(SRCDIR)/json_config.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_config.c >$(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.o:	$(OBJDIR)/json_config_.c $(OBJDIR)/json_config.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_config.o -c $(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.h:	$(OBJDIR)/headers

$(OBJDIR)/json_diff_.c:	$(SRCDIR)/json_diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.o:	$(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.h:	$(OBJDIR)/headers

$(OBJDIR)/json_dir_.c:	$(SRCDIR)/json_dir.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_dir.c >$(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.o:	$(OBJDIR)/json_dir_.c $(OBJDIR)/json_dir.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_dir.o -c $(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.h:	$(OBJDIR)/headers

$(OBJDIR)/json_finfo_.c:	$(SRCDIR)/json_finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_finfo.c >$(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.o:	$(OBJDIR)/json_finfo_.c $(OBJDIR)/json_finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_finfo.o -c $(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/json_login_.c:	$(SRCDIR)/json_login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.o:	$(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.h:	$(OBJDIR)/headers

$(OBJDIR)/json_query_.c:	$(SRCDIR)/json_query.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.o:	$(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.h:	$(OBJDIR)/headers

$(OBJDIR)/json_report_.c:	$(SRCDIR)/json_report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.o:	$(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.h:	$(OBJDIR)/headers

$(OBJDIR)/json_status_.c:	$(SRCDIR)/json_status.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_status.c >$(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.o:	$(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.h:	$(OBJDIR)/headers

$(OBJDIR)/json_tag_.c:	$(SRCDIR)/json_tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.o:	$(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.h:	$(OBJDIR)/headers

$(OBJDIR)/json_timeline_.c:	$(SRCDIR)/json_timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.o:	$(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/json_user_.c:	$(SRCDIR)/json_user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.o:	$(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.h:	$(OBJDIR)/headers

$(OBJDIR)/json_wiki_.c:	$(SRCDIR)/json_wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.o:	$(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/leaf_.c:	$(SRCDIR)/leaf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.o:	$(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.h:	$(OBJDIR)/headers

$(OBJDIR)/loadctrl_.c:	$(SRCDIR)/loadctrl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/loadctrl.c >$(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.o:	$(OBJDIR)/loadctrl_.c $(OBJDIR)/loadctrl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/loadctrl.o -c $(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.h:	$(OBJDIR)/headers

$(OBJDIR)/login_.c:	$(SRCDIR)/login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/login.c >$(OBJDIR)/login_.c

$(OBJDIR)/login.o:	$(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c

$(OBJDIR)/login.h:	$(OBJDIR)/headers

$(OBJDIR)/lookslike_.c:	$(SRCDIR)/lookslike.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.o:	$(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.h:	$(OBJDIR)/headers

$(OBJDIR)/main_.c:	$(SRCDIR)/main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c

$(OBJDIR)/main.o:	$(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c

$(OBJDIR)/main.h:	$(OBJDIR)/headers

$(OBJDIR)/manifest_.c:	$(SRCDIR)/manifest.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/manifest.c >$(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.o:	$(OBJDIR)/manifest_.c $(OBJDIR)/manifest.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c $(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_.c:	$(SRCDIR)/markdown.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown.c >$(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.o:	$(OBJDIR)/markdown_.c $(OBJDIR)/markdown.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown.o -c $(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_html_.c:	$(SRCDIR)/markdown_html.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown_html.c >$(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.o:	$(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.h:	$(OBJDIR)/headers

$(OBJDIR)/md5_.c:	$(SRCDIR)/md5.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/md5.c >$(OBJDIR)/md5_.c

$(OBJDIR)/md5.o:	$(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c

$(OBJDIR)/md5.h:	$(OBJDIR)/headers

$(OBJDIR)/merge_.c:	$(SRCDIR)/merge.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge.c >$(OBJDIR)/merge_.c

$(OBJDIR)/merge.o:	$(OBJDIR)/merge_.c $(OBJDIR)/merge.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c $(OBJDIR)/merge_.c

$(OBJDIR)/merge.h:	$(OBJDIR)/headers

$(OBJDIR)/merge3_.c:	$(SRCDIR)/merge3.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge3.c >$(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.o:	$(OBJDIR)/merge3_.c $(OBJDIR)/merge3.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c $(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.h:	$(OBJDIR)/headers

$(OBJDIR)/moderate_.c:	$(SRCDIR)/moderate.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/moderate.c >$(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.o:	$(OBJDIR)/moderate_.c $(OBJDIR)/moderate.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/moderate.o -c $(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.h:	$(OBJDIR)/headers

$(OBJDIR)/name_.c:	$(SRCDIR)/name.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/name.c >$(OBJDIR)/name_.c

$(OBJDIR)/name.o:	$(OBJDIR)/name_.c $(OBJDIR)/name.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c $(OBJDIR)/name_.c

$(OBJDIR)/name.h:	$(OBJDIR)/headers

$(OBJDIR)/path_.c:	$(SRCDIR)/path.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/path.c >$(OBJDIR)/path_.c

$(OBJDIR)/path.o:	$(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c

$(OBJDIR)/path.h:	$(OBJDIR)/headers

$(OBJDIR)/pivot_.c:	$(SRCDIR)/pivot.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pivot.c >$(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.o:	$(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.h:	$(OBJDIR)/headers

$(OBJDIR)/popen_.c:	$(SRCDIR)/popen.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/popen.c >$(OBJDIR)/popen_.c

$(OBJDIR)/popen.o:	$(OBJDIR)/popen_.c $(OBJDIR)/popen.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/popen.o -c $(OBJDIR)/popen_.c

$(OBJDIR)/popen.h:	$(OBJDIR)/headers

$(OBJDIR)/pqueue_.c:	$(SRCDIR)/pqueue.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pqueue.c >$(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.o:	$(OBJDIR)/pqueue_.c $(OBJDIR)/pqueue.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c $(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.h:	$(OBJDIR)/headers

$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/printf.c >$(OBJDIR)/printf_.c

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rebuild.c >$(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.h:	$(OBJDIR)/headers

$(OBJDIR)/regexp_.c:	$(SRCDIR)/regexp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.o:	$(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.h:	$(OBJDIR)/headers

$(OBJDIR)/report_.c:	$(SRCDIR)/report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c

$(OBJDIR)/report.o:	$(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c

$(OBJDIR)/report.h:	$(OBJDIR)/headers

$(OBJDIR)/rss_.c:	$(SRCDIR)/rss.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rss.c >$(OBJDIR)/rss_.c

$(OBJDIR)/rss.o:	$(OBJDIR)/rss_.c $(OBJDIR)/rss.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c $(OBJDIR)/rss_.c

$(OBJDIR)/rss.h:	$(OBJDIR)/headers

$(OBJDIR)/schema_.c:	$(SRCDIR)/schema.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/schema.c >$(OBJDIR)/schema_.c

$(OBJDIR)/schema.o:	$(OBJDIR)/schema_.c $(OBJDIR)/schema.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c $(OBJDIR)/schema_.c

$(OBJDIR)/schema.h:	$(OBJDIR)/headers

$(OBJDIR)/search_.c:	$(SRCDIR)/search.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/search.c >$(OBJDIR)/search_.c

$(OBJDIR)/search.o:	$(OBJDIR)/search_.c $(OBJDIR)/search.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c $(OBJDIR)/search_.c

$(OBJDIR)/search.h:	$(OBJDIR)/headers

$(OBJDIR)/setup_.c:	$(SRCDIR)/setup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/setup.c >$(OBJDIR)/setup_.c

$(OBJDIR)/setup.o:	$(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c

$(OBJDIR)/setup.h:	$(OBJDIR)/headers

$(OBJDIR)/sha1_.c:	$(SRCDIR)/sha1.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sha1.c >$(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.o:	$(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.h:	$(OBJDIR)/headers

$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$(OBJDIR)/shun_.c

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$(OBJDIR)/skins_.c

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

$(OBJDIR)/skins.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlcmd_.c:	$(SRCDIR)/sqlcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sqlcmd.c >$(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.o:	$(OBJDIR)/sqlcmd_.c $(OBJDIR)/sqlcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sqlcmd.o -c $(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/stash_.c:	$(SRCDIR)/stash.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stash.c >$(OBJDIR)/stash_.c

$(OBJDIR)/stash.o:	$(OBJDIR)/stash_.c $(OBJDIR)/stash.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stash.o -c $(OBJDIR)/stash_.c

$(OBJDIR)/stash.h:	$(OBJDIR)/headers

$(OBJDIR)/stat_.c:	$(SRCDIR)/stat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stat.c >$(OBJDIR)/stat_.c

$(OBJDIR)/stat.o:	$(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c

$(OBJDIR)/stat.h:	$(OBJDIR)/headers

$(OBJDIR)/style_.c:	$(SRCDIR)/style.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/style.c >$(OBJDIR)/style_.c

$(OBJDIR)/style.o:	$(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c $(OBJDIR)/style_.c

$(OBJDIR)/style.h:	$(OBJDIR)/headers

$(OBJDIR)/sync_.c:	$(SRCDIR)/sync.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sync.c >$(OBJDIR)/sync_.c

$(OBJDIR)/sync.o:	$(OBJDIR)/sync_.c $(OBJDIR)/sync.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c $(OBJDIR)/sync_.c

$(OBJDIR)/sync.h:	$(OBJDIR)/headers

$(OBJDIR)/tag_.c:	$(SRCDIR)/tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tag.c >$(OBJDIR)/tag_.c

$(OBJDIR)/tag.o:	$(OBJDIR)/tag_.c $(OBJDIR)/tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c $(OBJDIR)/tag_.c

$(OBJDIR)/tag.h:	$(OBJDIR)/headers

$(OBJDIR)/tar_.c:	$(SRCDIR)/tar.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tar.c >$(OBJDIR)/tar_.c

$(OBJDIR)/tar.o:	$(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c

$(OBJDIR)/tar.h:	$(OBJDIR)/headers

$(OBJDIR)/th_main_.c:	$(SRCDIR)/th_main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/th_main.c >$(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.o:	$(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.h:	$(OBJDIR)/headers

$(OBJDIR)/timeline_.c:	$(SRCDIR)/timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/timeline.c >$(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.o:	$(OBJDIR)/timeline_.c $(OBJDIR)/timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c $(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/tkt_.c:	$(SRCDIR)/tkt.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tkt.c >$(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.o:	$(OBJDIR)/tkt_.c $(OBJDIR)/tkt.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c $(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.h:	$(OBJDIR)/headers

$(OBJDIR)/tktsetup_.c:	$(SRCDIR)/tktsetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tktsetup.c >$(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.o:	$(OBJDIR)/tktsetup_.c $(OBJDIR)/tktsetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c $(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.h:	$(OBJDIR)/headers

$(OBJDIR)/undo_.c:	$(SRCDIR)/undo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/undo.c >$(OBJDIR)/undo_.c

$(OBJDIR)/undo.o:	$(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c

$(OBJDIR)/undo.h:	$(OBJDIR)/headers

$(OBJDIR)/unicode_.c:	$(SRCDIR)/unicode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.o:	$(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.h:	$(OBJDIR)/headers

$(OBJDIR)/update_.c:	$(SRCDIR)/update.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c

$(OBJDIR)/update.o:	$(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c

$(OBJDIR)/update.h:	$(OBJDIR)/headers

$(OBJDIR)/url_.c:	$(SRCDIR)/url.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/url.c >$(OBJDIR)/url_.c

$(OBJDIR)/url.o:	$(OBJDIR)/url_.c $(OBJDIR)/url.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c $(OBJDIR)/url_.c

$(OBJDIR)/url.h:	$(OBJDIR)/headers

$(OBJDIR)/user_.c:	$(SRCDIR)/user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/user.c >$(OBJDIR)/user_.c

$(OBJDIR)/user.o:	$(OBJDIR)/user_.c $(OBJDIR)/user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c $(OBJDIR)/user_.c

$(OBJDIR)/user.h:	$(OBJDIR)/headers

$(OBJDIR)/utf8_.c:	$(SRCDIR)/utf8.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/utf8.c >$(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.o:	$(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.h:	$(OBJDIR)/headers

$(OBJDIR)/util_.c:	$(SRCDIR)/util.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/util.c >$(OBJDIR)/util_.c

$(OBJDIR)/util.o:	$(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c

$(OBJDIR)/util.h:	$(OBJDIR)/headers

$(OBJDIR)/verify_.c:	$(SRCDIR)/verify.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/verify.c >$(OBJDIR)/verify_.c

$(OBJDIR)/verify.o:	$(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c $(OBJDIR)/verify_.c

$(OBJDIR)/verify.h:	$(OBJDIR)/headers

$(OBJDIR)/vfile_.c:	$(SRCDIR)/vfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/vfile.c >$(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.o:	$(OBJDIR)/vfile_.c $(OBJDIR)/vfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c $(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.h:	$(OBJDIR)/headers

$(OBJDIR)/wiki_.c:	$(SRCDIR)/wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wiki.c >$(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.o:	$(OBJDIR)/wiki_.c $(OBJDIR)/wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c $(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/wikiformat_.c:	$(SRCDIR)/wikiformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wikiformat.c >$(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.o:	$(OBJDIR)/wikiformat_.c $(OBJDIR)/wikiformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c $(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.h:	$(OBJDIR)/headers

$(OBJDIR)/winfile_.c:	$(SRCDIR)/winfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winfile.c >$(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.o:	$(OBJDIR)/winfile_.c $(OBJDIR)/winfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winfile.o -c $(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.h:	$(OBJDIR)/headers

$(OBJDIR)/winhttp_.c:	$(SRCDIR)/winhttp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winhttp.c >$(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.o:	$(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.h:	$(OBJDIR)/headers

$(OBJDIR)/wysiwyg_.c:	$(SRCDIR)/wysiwyg.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wysiwyg.c >$(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.o:	$(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.h:	$(OBJDIR)/headers

$(OBJDIR)/xfer_.c:	$(SRCDIR)/xfer.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfer.c >$(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.o:	$(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.h:	$(OBJDIR)/headers

$(OBJDIR)/xfersetup_.c:	$(SRCDIR)/xfersetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfersetup.c >$(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.o:	$(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.h:	$(OBJDIR)/headers

$(OBJDIR)/zip_.c:	$(SRCDIR)/zip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/zip.c >$(OBJDIR)/zip_.c

$(OBJDIR)/zip.o:	$(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers

SQLITE_OPTIONS = -DNDEBUG=1 \







|







|







|







|







|







|







|







|






>
>
>
>
>
>
>
>

|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
	echo Done >$(OBJDIR)/headers

$(OBJDIR)/headers: Makefile

Makefile:

$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/add.c >$@

$(OBJDIR)/add.o:	$(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c

$(OBJDIR)/add.h:	$(OBJDIR)/headers

$(OBJDIR)/allrepo_.c:	$(SRCDIR)/allrepo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/allrepo.c >$@

$(OBJDIR)/allrepo.o:	$(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.h:	$(OBJDIR)/headers

$(OBJDIR)/attach_.c:	$(SRCDIR)/attach.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/attach.c >$@

$(OBJDIR)/attach.o:	$(OBJDIR)/attach_.c $(OBJDIR)/attach.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/attach.o -c $(OBJDIR)/attach_.c

$(OBJDIR)/attach.h:	$(OBJDIR)/headers

$(OBJDIR)/bag_.c:	$(SRCDIR)/bag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bag.c >$@

$(OBJDIR)/bag.o:	$(OBJDIR)/bag_.c $(OBJDIR)/bag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c $(OBJDIR)/bag_.c

$(OBJDIR)/bag.h:	$(OBJDIR)/headers

$(OBJDIR)/bisect_.c:	$(SRCDIR)/bisect.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bisect.c >$@

$(OBJDIR)/bisect.o:	$(OBJDIR)/bisect_.c $(OBJDIR)/bisect.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bisect.o -c $(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.h:	$(OBJDIR)/headers

$(OBJDIR)/blob_.c:	$(SRCDIR)/blob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/blob.c >$@

$(OBJDIR)/blob.o:	$(OBJDIR)/blob_.c $(OBJDIR)/blob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c $(OBJDIR)/blob_.c

$(OBJDIR)/blob.h:	$(OBJDIR)/headers

$(OBJDIR)/branch_.c:	$(SRCDIR)/branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/branch.c >$@

$(OBJDIR)/branch.o:	$(OBJDIR)/branch_.c $(OBJDIR)/branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c $(OBJDIR)/branch_.c

$(OBJDIR)/branch.h:	$(OBJDIR)/headers

$(OBJDIR)/browse_.c:	$(SRCDIR)/browse.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/browse.c >$@

$(OBJDIR)/browse.o:	$(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c

$(OBJDIR)/browse.h:	$(OBJDIR)/headers

$(OBJDIR)/builtin_.c:	$(SRCDIR)/builtin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/builtin.c >$@

$(OBJDIR)/builtin.o:	$(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c

$(OBJDIR)/builtin.h:	$(OBJDIR)/headers

$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cache.c >$@

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

$(OBJDIR)/cache.h:	$(OBJDIR)/headers

$(OBJDIR)/captcha_.c:	$(SRCDIR)/captcha.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/captcha.c >$@

$(OBJDIR)/captcha.o:	$(OBJDIR)/captcha_.c $(OBJDIR)/captcha.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c $(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.h:	$(OBJDIR)/headers

$(OBJDIR)/cgi_.c:	$(SRCDIR)/cgi.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cgi.c >$@

$(OBJDIR)/cgi.o:	$(OBJDIR)/cgi_.c $(OBJDIR)/cgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c $(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.h:	$(OBJDIR)/headers

$(OBJDIR)/checkin_.c:	$(SRCDIR)/checkin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkin.c >$@

$(OBJDIR)/checkin.o:	$(OBJDIR)/checkin_.c $(OBJDIR)/checkin.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c $(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.h:	$(OBJDIR)/headers

$(OBJDIR)/checkout_.c:	$(SRCDIR)/checkout.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkout.c >$@

$(OBJDIR)/checkout.o:	$(OBJDIR)/checkout_.c $(OBJDIR)/checkout.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c $(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.h:	$(OBJDIR)/headers

$(OBJDIR)/clearsign_.c:	$(SRCDIR)/clearsign.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clearsign.c >$@

$(OBJDIR)/clearsign.o:	$(OBJDIR)/clearsign_.c $(OBJDIR)/clearsign.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c $(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.h:	$(OBJDIR)/headers

$(OBJDIR)/clone_.c:	$(SRCDIR)/clone.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clone.c >$@

$(OBJDIR)/clone.o:	$(OBJDIR)/clone_.c $(OBJDIR)/clone.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c $(OBJDIR)/clone_.c

$(OBJDIR)/clone.h:	$(OBJDIR)/headers

$(OBJDIR)/comformat_.c:	$(SRCDIR)/comformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/comformat.c >$@

$(OBJDIR)/comformat.o:	$(OBJDIR)/comformat_.c $(OBJDIR)/comformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c $(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.h:	$(OBJDIR)/headers

$(OBJDIR)/configure_.c:	$(SRCDIR)/configure.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/configure.c >$@

$(OBJDIR)/configure.o:	$(OBJDIR)/configure_.c $(OBJDIR)/configure.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c $(OBJDIR)/configure_.c

$(OBJDIR)/configure.h:	$(OBJDIR)/headers

$(OBJDIR)/content_.c:	$(SRCDIR)/content.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/content.c >$@

$(OBJDIR)/content.o:	$(OBJDIR)/content_.c $(OBJDIR)/content.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c $(OBJDIR)/content_.c

$(OBJDIR)/content.h:	$(OBJDIR)/headers

$(OBJDIR)/db_.c:	$(SRCDIR)/db.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/db.c >$@

$(OBJDIR)/db.o:	$(OBJDIR)/db_.c $(OBJDIR)/db.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c $(OBJDIR)/db_.c

$(OBJDIR)/db.h:	$(OBJDIR)/headers

$(OBJDIR)/delta_.c:	$(SRCDIR)/delta.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/delta.c >$@

$(OBJDIR)/delta.o:	$(OBJDIR)/delta_.c $(OBJDIR)/delta.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c $(OBJDIR)/delta_.c

$(OBJDIR)/delta.h:	$(OBJDIR)/headers

$(OBJDIR)/deltacmd_.c:	$(SRCDIR)/deltacmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/deltacmd.c >$@

$(OBJDIR)/deltacmd.o:	$(OBJDIR)/deltacmd_.c $(OBJDIR)/deltacmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c $(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.h:	$(OBJDIR)/headers

$(OBJDIR)/descendants_.c:	$(SRCDIR)/descendants.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/descendants.c >$@

$(OBJDIR)/descendants.o:	$(OBJDIR)/descendants_.c $(OBJDIR)/descendants.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c $(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.h:	$(OBJDIR)/headers

$(OBJDIR)/diff_.c:	$(SRCDIR)/diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diff.c >$@

$(OBJDIR)/diff.o:	$(OBJDIR)/diff_.c $(OBJDIR)/diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c $(OBJDIR)/diff_.c

$(OBJDIR)/diff.h:	$(OBJDIR)/headers

$(OBJDIR)/diffcmd_.c:	$(SRCDIR)/diffcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diffcmd.c >$@

$(OBJDIR)/diffcmd.o:	$(OBJDIR)/diffcmd_.c $(OBJDIR)/diffcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c $(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/doc_.c:	$(SRCDIR)/doc.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/doc.c >$@

$(OBJDIR)/doc.o:	$(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c

$(OBJDIR)/doc.h:	$(OBJDIR)/headers

$(OBJDIR)/encode_.c:	$(SRCDIR)/encode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/encode.c >$@

$(OBJDIR)/encode.o:	$(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c

$(OBJDIR)/encode.h:	$(OBJDIR)/headers

$(OBJDIR)/event_.c:	$(SRCDIR)/event.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/event.c >$@

$(OBJDIR)/event.o:	$(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/event.o -c $(OBJDIR)/event_.c

$(OBJDIR)/event.h:	$(OBJDIR)/headers

$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/export.c >$@

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/file.c >$@

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

$(OBJDIR)/file.h:	$(OBJDIR)/headers

$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$@

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.h:	$(OBJDIR)/headers

$(OBJDIR)/glob_.c:	$(SRCDIR)/glob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/glob.c >$@

$(OBJDIR)/glob.o:	$(OBJDIR)/glob_.c $(OBJDIR)/glob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/glob.o -c $(OBJDIR)/glob_.c

$(OBJDIR)/glob.h:	$(OBJDIR)/headers

$(OBJDIR)/graph_.c:	$(SRCDIR)/graph.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/graph.c >$@

$(OBJDIR)/graph.o:	$(OBJDIR)/graph_.c $(OBJDIR)/graph.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c $(OBJDIR)/graph_.c

$(OBJDIR)/graph.h:	$(OBJDIR)/headers

$(OBJDIR)/gzip_.c:	$(SRCDIR)/gzip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/gzip.c >$@

$(OBJDIR)/gzip.o:	$(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.h:	$(OBJDIR)/headers

$(OBJDIR)/http_.c:	$(SRCDIR)/http.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http.c >$@

$(OBJDIR)/http.o:	$(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c

$(OBJDIR)/http.h:	$(OBJDIR)/headers

$(OBJDIR)/http_socket_.c:	$(SRCDIR)/http_socket.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_socket.c >$@

$(OBJDIR)/http_socket.o:	$(OBJDIR)/http_socket_.c $(OBJDIR)/http_socket.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c $(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.h:	$(OBJDIR)/headers

$(OBJDIR)/http_ssl_.c:	$(SRCDIR)/http_ssl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_ssl.c >$@

$(OBJDIR)/http_ssl.o:	$(OBJDIR)/http_ssl_.c $(OBJDIR)/http_ssl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_ssl.o -c $(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.h:	$(OBJDIR)/headers

$(OBJDIR)/http_transport_.c:	$(SRCDIR)/http_transport.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_transport.c >$@

$(OBJDIR)/http_transport.o:	$(OBJDIR)/http_transport_.c $(OBJDIR)/http_transport.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c $(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.h:	$(OBJDIR)/headers

$(OBJDIR)/import_.c:	$(SRCDIR)/import.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/import.c >$@

$(OBJDIR)/import.o:	$(OBJDIR)/import_.c $(OBJDIR)/import.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/import.o -c $(OBJDIR)/import_.c

$(OBJDIR)/import.h:	$(OBJDIR)/headers

$(OBJDIR)/info_.c:	$(SRCDIR)/info.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/info.c >$@

$(OBJDIR)/info.o:	$(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c

$(OBJDIR)/info.h:	$(OBJDIR)/headers

$(OBJDIR)/json_.c:	$(SRCDIR)/json.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json.c >$@

$(OBJDIR)/json.o:	$(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c

$(OBJDIR)/json.h:	$(OBJDIR)/headers

$(OBJDIR)/json_artifact_.c:	$(SRCDIR)/json_artifact.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_artifact.c >$@

$(OBJDIR)/json_artifact.o:	$(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.h:	$(OBJDIR)/headers

$(OBJDIR)/json_branch_.c:	$(SRCDIR)/json_branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_branch.c >$@

$(OBJDIR)/json_branch.o:	$(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.h:	$(OBJDIR)/headers

$(OBJDIR)/json_config_.c:	$(SRCDIR)/json_config.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_config.c >$@

$(OBJDIR)/json_config.o:	$(OBJDIR)/json_config_.c $(OBJDIR)/json_config.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_config.o -c $(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.h:	$(OBJDIR)/headers

$(OBJDIR)/json_diff_.c:	$(SRCDIR)/json_diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_diff.c >$@

$(OBJDIR)/json_diff.o:	$(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.h:	$(OBJDIR)/headers

$(OBJDIR)/json_dir_.c:	$(SRCDIR)/json_dir.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_dir.c >$@

$(OBJDIR)/json_dir.o:	$(OBJDIR)/json_dir_.c $(OBJDIR)/json_dir.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_dir.o -c $(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.h:	$(OBJDIR)/headers

$(OBJDIR)/json_finfo_.c:	$(SRCDIR)/json_finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_finfo.c >$@

$(OBJDIR)/json_finfo.o:	$(OBJDIR)/json_finfo_.c $(OBJDIR)/json_finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_finfo.o -c $(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/json_login_.c:	$(SRCDIR)/json_login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_login.c >$@

$(OBJDIR)/json_login.o:	$(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.h:	$(OBJDIR)/headers

$(OBJDIR)/json_query_.c:	$(SRCDIR)/json_query.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_query.c >$@

$(OBJDIR)/json_query.o:	$(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.h:	$(OBJDIR)/headers

$(OBJDIR)/json_report_.c:	$(SRCDIR)/json_report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_report.c >$@

$(OBJDIR)/json_report.o:	$(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.h:	$(OBJDIR)/headers

$(OBJDIR)/json_status_.c:	$(SRCDIR)/json_status.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_status.c >$@

$(OBJDIR)/json_status.o:	$(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.h:	$(OBJDIR)/headers

$(OBJDIR)/json_tag_.c:	$(SRCDIR)/json_tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_tag.c >$@

$(OBJDIR)/json_tag.o:	$(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.h:	$(OBJDIR)/headers

$(OBJDIR)/json_timeline_.c:	$(SRCDIR)/json_timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_timeline.c >$@

$(OBJDIR)/json_timeline.o:	$(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/json_user_.c:	$(SRCDIR)/json_user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_user.c >$@

$(OBJDIR)/json_user.o:	$(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.h:	$(OBJDIR)/headers

$(OBJDIR)/json_wiki_.c:	$(SRCDIR)/json_wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_wiki.c >$@

$(OBJDIR)/json_wiki.o:	$(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/leaf_.c:	$(SRCDIR)/leaf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/leaf.c >$@

$(OBJDIR)/leaf.o:	$(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.h:	$(OBJDIR)/headers

$(OBJDIR)/loadctrl_.c:	$(SRCDIR)/loadctrl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/loadctrl.c >$@

$(OBJDIR)/loadctrl.o:	$(OBJDIR)/loadctrl_.c $(OBJDIR)/loadctrl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/loadctrl.o -c $(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.h:	$(OBJDIR)/headers

$(OBJDIR)/login_.c:	$(SRCDIR)/login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/login.c >$@

$(OBJDIR)/login.o:	$(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c

$(OBJDIR)/login.h:	$(OBJDIR)/headers

$(OBJDIR)/lookslike_.c:	$(SRCDIR)/lookslike.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/lookslike.c >$@

$(OBJDIR)/lookslike.o:	$(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.h:	$(OBJDIR)/headers

$(OBJDIR)/main_.c:	$(SRCDIR)/main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/main.c >$@

$(OBJDIR)/main.o:	$(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c

$(OBJDIR)/main.h:	$(OBJDIR)/headers

$(OBJDIR)/manifest_.c:	$(SRCDIR)/manifest.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/manifest.c >$@

$(OBJDIR)/manifest.o:	$(OBJDIR)/manifest_.c $(OBJDIR)/manifest.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c $(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_.c:	$(SRCDIR)/markdown.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown.c >$@

$(OBJDIR)/markdown.o:	$(OBJDIR)/markdown_.c $(OBJDIR)/markdown.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown.o -c $(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_html_.c:	$(SRCDIR)/markdown_html.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown_html.c >$@

$(OBJDIR)/markdown_html.o:	$(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.h:	$(OBJDIR)/headers

$(OBJDIR)/md5_.c:	$(SRCDIR)/md5.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/md5.c >$@

$(OBJDIR)/md5.o:	$(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c

$(OBJDIR)/md5.h:	$(OBJDIR)/headers

$(OBJDIR)/merge_.c:	$(SRCDIR)/merge.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge.c >$@

$(OBJDIR)/merge.o:	$(OBJDIR)/merge_.c $(OBJDIR)/merge.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c $(OBJDIR)/merge_.c

$(OBJDIR)/merge.h:	$(OBJDIR)/headers

$(OBJDIR)/merge3_.c:	$(SRCDIR)/merge3.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge3.c >$@

$(OBJDIR)/merge3.o:	$(OBJDIR)/merge3_.c $(OBJDIR)/merge3.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c $(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.h:	$(OBJDIR)/headers

$(OBJDIR)/moderate_.c:	$(SRCDIR)/moderate.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/moderate.c >$@

$(OBJDIR)/moderate.o:	$(OBJDIR)/moderate_.c $(OBJDIR)/moderate.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/moderate.o -c $(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.h:	$(OBJDIR)/headers

$(OBJDIR)/name_.c:	$(SRCDIR)/name.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/name.c >$@

$(OBJDIR)/name.o:	$(OBJDIR)/name_.c $(OBJDIR)/name.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c $(OBJDIR)/name_.c

$(OBJDIR)/name.h:	$(OBJDIR)/headers

$(OBJDIR)/path_.c:	$(SRCDIR)/path.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/path.c >$@

$(OBJDIR)/path.o:	$(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c

$(OBJDIR)/path.h:	$(OBJDIR)/headers

$(OBJDIR)/pivot_.c:	$(SRCDIR)/pivot.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pivot.c >$@

$(OBJDIR)/pivot.o:	$(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.h:	$(OBJDIR)/headers

$(OBJDIR)/popen_.c:	$(SRCDIR)/popen.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/popen.c >$@

$(OBJDIR)/popen.o:	$(OBJDIR)/popen_.c $(OBJDIR)/popen.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/popen.o -c $(OBJDIR)/popen_.c

$(OBJDIR)/popen.h:	$(OBJDIR)/headers

$(OBJDIR)/pqueue_.c:	$(SRCDIR)/pqueue.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pqueue.c >$@

$(OBJDIR)/pqueue.o:	$(OBJDIR)/pqueue_.c $(OBJDIR)/pqueue.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c $(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.h:	$(OBJDIR)/headers

$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/printf.c >$@

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rebuild.c >$@

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.h:	$(OBJDIR)/headers

$(OBJDIR)/regexp_.c:	$(SRCDIR)/regexp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/regexp.c >$@

$(OBJDIR)/regexp.o:	$(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.h:	$(OBJDIR)/headers

$(OBJDIR)/report_.c:	$(SRCDIR)/report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/report.c >$@

$(OBJDIR)/report.o:	$(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c

$(OBJDIR)/report.h:	$(OBJDIR)/headers

$(OBJDIR)/rss_.c:	$(SRCDIR)/rss.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rss.c >$@

$(OBJDIR)/rss.o:	$(OBJDIR)/rss_.c $(OBJDIR)/rss.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c $(OBJDIR)/rss_.c

$(OBJDIR)/rss.h:	$(OBJDIR)/headers

$(OBJDIR)/schema_.c:	$(SRCDIR)/schema.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/schema.c >$@

$(OBJDIR)/schema.o:	$(OBJDIR)/schema_.c $(OBJDIR)/schema.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c $(OBJDIR)/schema_.c

$(OBJDIR)/schema.h:	$(OBJDIR)/headers

$(OBJDIR)/search_.c:	$(SRCDIR)/search.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/search.c >$@

$(OBJDIR)/search.o:	$(OBJDIR)/search_.c $(OBJDIR)/search.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c $(OBJDIR)/search_.c

$(OBJDIR)/search.h:	$(OBJDIR)/headers

$(OBJDIR)/setup_.c:	$(SRCDIR)/setup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/setup.c >$@

$(OBJDIR)/setup.o:	$(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c

$(OBJDIR)/setup.h:	$(OBJDIR)/headers

$(OBJDIR)/sha1_.c:	$(SRCDIR)/sha1.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sha1.c >$@

$(OBJDIR)/sha1.o:	$(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.h:	$(OBJDIR)/headers

$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

$(OBJDIR)/skins.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlcmd_.c:	$(SRCDIR)/sqlcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sqlcmd.c >$@

$(OBJDIR)/sqlcmd.o:	$(OBJDIR)/sqlcmd_.c $(OBJDIR)/sqlcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sqlcmd.o -c $(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/stash_.c:	$(SRCDIR)/stash.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stash.c >$@

$(OBJDIR)/stash.o:	$(OBJDIR)/stash_.c $(OBJDIR)/stash.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stash.o -c $(OBJDIR)/stash_.c

$(OBJDIR)/stash.h:	$(OBJDIR)/headers

$(OBJDIR)/stat_.c:	$(SRCDIR)/stat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stat.c >$@

$(OBJDIR)/stat.o:	$(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c

$(OBJDIR)/stat.h:	$(OBJDIR)/headers

$(OBJDIR)/style_.c:	$(SRCDIR)/style.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/style.c >$@

$(OBJDIR)/style.o:	$(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c $(OBJDIR)/style_.c

$(OBJDIR)/style.h:	$(OBJDIR)/headers

$(OBJDIR)/sync_.c:	$(SRCDIR)/sync.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sync.c >$@

$(OBJDIR)/sync.o:	$(OBJDIR)/sync_.c $(OBJDIR)/sync.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c $(OBJDIR)/sync_.c

$(OBJDIR)/sync.h:	$(OBJDIR)/headers

$(OBJDIR)/tag_.c:	$(SRCDIR)/tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tag.c >$@

$(OBJDIR)/tag.o:	$(OBJDIR)/tag_.c $(OBJDIR)/tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c $(OBJDIR)/tag_.c

$(OBJDIR)/tag.h:	$(OBJDIR)/headers

$(OBJDIR)/tar_.c:	$(SRCDIR)/tar.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tar.c >$@

$(OBJDIR)/tar.o:	$(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c

$(OBJDIR)/tar.h:	$(OBJDIR)/headers

$(OBJDIR)/th_main_.c:	$(SRCDIR)/th_main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/th_main.c >$@

$(OBJDIR)/th_main.o:	$(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.h:	$(OBJDIR)/headers

$(OBJDIR)/timeline_.c:	$(SRCDIR)/timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/timeline.c >$@

$(OBJDIR)/timeline.o:	$(OBJDIR)/timeline_.c $(OBJDIR)/timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c $(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/tkt_.c:	$(SRCDIR)/tkt.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tkt.c >$@

$(OBJDIR)/tkt.o:	$(OBJDIR)/tkt_.c $(OBJDIR)/tkt.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c $(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.h:	$(OBJDIR)/headers

$(OBJDIR)/tktsetup_.c:	$(SRCDIR)/tktsetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tktsetup.c >$@

$(OBJDIR)/tktsetup.o:	$(OBJDIR)/tktsetup_.c $(OBJDIR)/tktsetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c $(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.h:	$(OBJDIR)/headers

$(OBJDIR)/undo_.c:	$(SRCDIR)/undo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/undo.c >$@

$(OBJDIR)/undo.o:	$(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c

$(OBJDIR)/undo.h:	$(OBJDIR)/headers

$(OBJDIR)/unicode_.c:	$(SRCDIR)/unicode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/unicode.c >$@

$(OBJDIR)/unicode.o:	$(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.h:	$(OBJDIR)/headers

$(OBJDIR)/update_.c:	$(SRCDIR)/update.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/update.c >$@

$(OBJDIR)/update.o:	$(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c

$(OBJDIR)/update.h:	$(OBJDIR)/headers

$(OBJDIR)/url_.c:	$(SRCDIR)/url.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/url.c >$@

$(OBJDIR)/url.o:	$(OBJDIR)/url_.c $(OBJDIR)/url.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c $(OBJDIR)/url_.c

$(OBJDIR)/url.h:	$(OBJDIR)/headers

$(OBJDIR)/user_.c:	$(SRCDIR)/user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/user.c >$@

$(OBJDIR)/user.o:	$(OBJDIR)/user_.c $(OBJDIR)/user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c $(OBJDIR)/user_.c

$(OBJDIR)/user.h:	$(OBJDIR)/headers

$(OBJDIR)/utf8_.c:	$(SRCDIR)/utf8.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/utf8.c >$@

$(OBJDIR)/utf8.o:	$(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.h:	$(OBJDIR)/headers

$(OBJDIR)/util_.c:	$(SRCDIR)/util.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/util.c >$@

$(OBJDIR)/util.o:	$(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c

$(OBJDIR)/util.h:	$(OBJDIR)/headers

$(OBJDIR)/verify_.c:	$(SRCDIR)/verify.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/verify.c >$@

$(OBJDIR)/verify.o:	$(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c $(OBJDIR)/verify_.c

$(OBJDIR)/verify.h:	$(OBJDIR)/headers

$(OBJDIR)/vfile_.c:	$(SRCDIR)/vfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/vfile.c >$@

$(OBJDIR)/vfile.o:	$(OBJDIR)/vfile_.c $(OBJDIR)/vfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c $(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.h:	$(OBJDIR)/headers

$(OBJDIR)/wiki_.c:	$(SRCDIR)/wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wiki.c >$@

$(OBJDIR)/wiki.o:	$(OBJDIR)/wiki_.c $(OBJDIR)/wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c $(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/wikiformat_.c:	$(SRCDIR)/wikiformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wikiformat.c >$@

$(OBJDIR)/wikiformat.o:	$(OBJDIR)/wikiformat_.c $(OBJDIR)/wikiformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c $(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.h:	$(OBJDIR)/headers

$(OBJDIR)/winfile_.c:	$(SRCDIR)/winfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winfile.c >$@

$(OBJDIR)/winfile.o:	$(OBJDIR)/winfile_.c $(OBJDIR)/winfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winfile.o -c $(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.h:	$(OBJDIR)/headers

$(OBJDIR)/winhttp_.c:	$(SRCDIR)/winhttp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winhttp.c >$@

$(OBJDIR)/winhttp.o:	$(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.h:	$(OBJDIR)/headers

$(OBJDIR)/wysiwyg_.c:	$(SRCDIR)/wysiwyg.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wysiwyg.c >$@

$(OBJDIR)/wysiwyg.o:	$(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.h:	$(OBJDIR)/headers

$(OBJDIR)/xfer_.c:	$(SRCDIR)/xfer.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfer.c >$@

$(OBJDIR)/xfer.o:	$(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.h:	$(OBJDIR)/headers

$(OBJDIR)/xfersetup_.c:	$(SRCDIR)/xfersetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfersetup.c >$@

$(OBJDIR)/xfersetup.o:	$(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.h:	$(OBJDIR)/headers

$(OBJDIR)/zip_.c:	$(SRCDIR)/zip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/zip.c >$@

$(OBJDIR)/zip.o:	$(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers

SQLITE_OPTIONS = -DNDEBUG=1 \
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
                -Dfopen=fossil_fopen

MINIZ_OPTIONS = -DMINIZ_NO_STDIO \
                -DMINIZ_NO_TIME \
                -DMINIZ_NO_ARCHIVE_APIS

$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw
	$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/cson_amalgamation.o:	$(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o

$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(SRCDIR)/../win/Makefile.mingw
	$(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o

$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o

$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $(OBJDIR)/miniz.o








|


|




|


|


|


|


|

1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
                -Dfopen=fossil_fopen

MINIZ_OPTIONS = -DMINIZ_NO_STDIO \
                -DMINIZ_NO_TIME \
                -DMINIZ_NO_ARCHIVE_APIS

$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw
	$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $@

$(OBJDIR)/cson_amalgamation.o:	$(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $@

$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(SRCDIR)/../win/Makefile.mingw
	$(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $@

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $@

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $@

$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -c $(SRCDIR)/th_tcl.c -o $@

$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $@

Changes to win/Makefile.mingw.mistachkin.
97
98
99
100
101
102
103




















104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib





















#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
#    Fossil source code directory and the target OpenSSL source directory.
#
OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i

#### Either the directory where the Tcl library is installed or the Tcl
#    source code directory resides (depending on the value of the macro
#    FOSSIL_TCL_SOURCE).  If this points to the Tcl install directory,
#    this directory must have "include" and "lib" sub-directories.  If
#    this points to the Tcl source code directory, this directory must
#    have "generic" and "win" sub-directories.  The recommended usage







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib

ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif

ifndef X64
SSLCONFIG = mingw
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else
SSLCONFIG = mingw64
ZLIBCONFIG = 
LIBTARGETS =
endif

ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
#    Fossil source code directory and the target OpenSSL source directory.
#
OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j

#### Either the directory where the Tcl library is installed or the Tcl
#    source code directory resides (depending on the value of the macro
#    FOSSIL_TCL_SOURCE).  If this points to the Tcl install directory,
#    this directory must have "include" and "lib" sub-directories.  If
#    this points to the Tcl source code directory, this directory must
#    have "generic" and "win" sub-directories.  The recommended usage
329
330
331
332
333
334
335

336
337
338
339
340
341
342
  $(SRCDIR)/allrepo.c \
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \

  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \







>







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
  $(SRCDIR)/allrepo.c \
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \
  $(SRCDIR)/builtin.c \
  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \
433
434
435
436
437
438
439



440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
  $(SRCDIR)/winfile.c \
  $(SRCDIR)/winhttp.c \
  $(SRCDIR)/wysiwyg.c \
  $(SRCDIR)/xfer.c \
  $(SRCDIR)/xfersetup.c \
  $(SRCDIR)/zip.c




TRANS_SRC = \
  $(OBJDIR)/add_.c \
  $(OBJDIR)/allrepo_.c \
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \

  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \







>
>
>









>







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  $(SRCDIR)/winfile.c \
  $(SRCDIR)/winhttp.c \
  $(SRCDIR)/wysiwyg.c \
  $(SRCDIR)/xfer.c \
  $(SRCDIR)/xfersetup.c \
  $(SRCDIR)/zip.c

EXTRA_FILES = \
  $(SRCDIR)/diff.tcl

TRANS_SRC = \
  $(OBJDIR)/add_.c \
  $(OBJDIR)/allrepo_.c \
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \
  $(OBJDIR)/builtin_.c \
  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \
555
556
557
558
559
560
561

562
563
564
565
566
567
568
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \

 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \







>







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \
 $(OBJDIR)/builtin.o \
 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681


682
683
684
685
686
687
688
689
690
691
692
693


694
695
696
697
698
699
700
 $(OBJDIR)/wysiwyg.o \
 $(OBJDIR)/xfer.o \
 $(OBJDIR)/xfersetup.o \
 $(OBJDIR)/zip.o

APPNAME    = fossil.exe
APPTARGETS =
LIBTARGETS =

#### If the USE_WINDOWS variable exists, it is assumed that we are building
#    inside of a Windows-style shell; otherwise, it is assumed that we are
#    building inside of a Unix-style shell.  Note that the "move" command is
#    broken when attempting to use it from the Windows shell via MinGW make
#    because the SHELL variable is only used for certain commands that are
#    recognized internally by make.
#
ifdef USE_WINDOWS
TRANSLATE   = $(subst /,\,$(OBJDIR)/translate.exe)
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
MKINDEX     = $(subst /,\,$(OBJDIR)/mkindex.exe)
VERSION     = $(subst /,\,$(OBJDIR)/version.exe)


CAT         = type
CP          = copy
GREP        = find
MV          = copy
RM          = del /Q
MKDIR       = -mkdir
RMDIR       = rmdir /S /Q
else
TRANSLATE   = $(OBJDIR)/translate.exe
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
MKINDEX     = $(OBJDIR)/mkindex.exe
VERSION     = $(OBJDIR)/version.exe


CAT         = cat
CP          = cp
GREP        = grep
MV          = mv
RM          = rm -f
MKDIR       = -mkdir -p
RMDIR       = rm -rf







<












|
>
>











|
>
>







687
688
689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
 $(OBJDIR)/wysiwyg.o \
 $(OBJDIR)/xfer.o \
 $(OBJDIR)/xfersetup.o \
 $(OBJDIR)/zip.o

APPNAME    = fossil.exe
APPTARGETS =


#### If the USE_WINDOWS variable exists, it is assumed that we are building
#    inside of a Windows-style shell; otherwise, it is assumed that we are
#    building inside of a Unix-style shell.  Note that the "move" command is
#    broken when attempting to use it from the Windows shell via MinGW make
#    because the SHELL variable is only used for certain commands that are
#    recognized internally by make.
#
ifdef USE_WINDOWS
TRANSLATE   = $(subst /,\,$(OBJDIR)/translate.exe)
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
MKINDEX     = $(subst /,\,$(OBJDIR)/mkindex.exe)
MKBUILTIN   = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
MKVERSION   = $(subst /,\,$(OBJDIR)/mkversion.exe)
CODECHECK1  = $(subst /,\,$(OBJDIR)/codecheck1.exe)
CAT         = type
CP          = copy
GREP        = find
MV          = copy
RM          = del /Q
MKDIR       = -mkdir
RMDIR       = rmdir /S /Q
else
TRANSLATE   = $(OBJDIR)/translate.exe
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
MKINDEX     = $(OBJDIR)/mkindex.exe
MKBUILTIN   = $(OBJDIR)/mkbuiltin.exe
MKVERSION   = $(OBJDIR)/mkversion.exe
CODECHECK1  = $(OBJDIR)/codecheck1.exe
CAT         = cat
CP          = cp
GREP        = grep
MV          = mv
RM          = rm -f
MKDIR       = -mkdir -p
RMDIR       = rm -rf
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743



744
745



746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
ifdef USE_WINDOWS
	$(MKDIR) $(subst /,\,$(OBJDIR))
else
	$(MKDIR) $(OBJDIR)
endif

$(TRANSLATE):	$(SRCDIR)/translate.c
	$(BCC) -o $(TRANSLATE) $(SRCDIR)/translate.c

$(MAKEHEADERS):	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c

$(MKINDEX):	$(SRCDIR)/mkindex.c
	$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c




$(VERSION): $(SRCDIR)/mkversion.c
	$(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c




# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
	$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h

# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
# to 1. If it is set to 1, then there is no need to build or link
# the sqlite3.o object. Instead, the system SQLite will be linked
# using -lsqlite3.
SQLITE3_OBJ.1 =
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o







|


|


|

>
>
>
|
|
>
>
>







|
|







758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
ifdef USE_WINDOWS
	$(MKDIR) $(subst /,\,$(OBJDIR))
else
	$(MKDIR) $(OBJDIR)
endif

$(TRANSLATE):	$(SRCDIR)/translate.c
	$(BCC) -o $@ $(SRCDIR)/translate.c

$(MAKEHEADERS):	$(SRCDIR)/makeheaders.c
	$(BCC) -o $@ $(SRCDIR)/makeheaders.c

$(MKINDEX):	$(SRCDIR)/mkindex.c
	$(BCC) -o $@ $(SRCDIR)/mkindex.c

$(MKBUILTIN):	$(SRCDIR)/mkbuiltin.c
	$(BCC) -o $@ $(SRCDIR)/mkbuiltin.c

$(MKVERSION): $(SRCDIR)/mkversion.c
	$(BCC) -o $@ $(SRCDIR)/mkversion.c

$(CODECHECK1):	$(SRCDIR)/codecheck1.c
	$(BCC) -o $@ $(SRCDIR)/codecheck1.c

# WARNING. DANGER. Running the test suite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
	$(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$@

# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
# to 1. If it is set to 1, then there is no need to build or link
# the sqlite3.o object. Instead, the system SQLite will be linked
# using -lsqlite3.
SQLITE3_OBJ.1 =
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o
776
777
778
779
780
781
782
783
784
785
786







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
 $(OBJDIR)/th.o \
 $(OBJDIR)/th_lang.o \
 $(OBJDIR)/th_tcl.o \
 $(OBJDIR)/cson_amalgamation.o


zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a

clean-zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean








ifndef FOSSIL_ENABLE_MINIZ
LIBTARGETS += zlib
endif

openssl:	$(LIBTARGETS)
ifndef FOSSIL_ENABLE_MINIZ
	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib mingw
else
	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) mingw
endif
	$(MAKE) -C $(OPENSSLLIBDIR) build_libs

clean-openssl:
	$(MAKE) -C $(OPENSSLLIBDIR) clean

tcl:
	cd $(TCLSRCDIR)/win;./configure
	$(MAKE) -C $(TCLSRCDIR)/win $(TCLTARGET)

clean-tcl:
	$(MAKE) -C $(TCLSRCDIR)/win distclean

APPTARGETS += $(LIBTARGETS)

ifdef FOSSIL_BUILD_SSL
APPTARGETS += openssl
endif

$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)

	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o

# 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:
	# noop








|



>
>
>
>
>
>
>






<
<
<
|
<


















|
>
|







811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834



835

836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
 $(OBJDIR)/th.o \
 $(OBJDIR)/th_lang.o \
 $(OBJDIR)/th_tcl.o \
 $(OBJDIR)/cson_amalgamation.o


zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) $(ZLIBCONFIG) -f win32/Makefile.gcc libz.a

clean-zlib:
	$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean

$(ZLIBDIR)/inffas86.o:
	$(TCC) -c -o $@ -DASMINF -I$(ZLIBDIR) -O3 $(ZLIBDIR)/contrib/inflate86/inffas86.c

$(ZLIBDIR)/match.o:
	$(TCC) -c -o $@ -DASMV $(ZLIBDIR)/contrib/asm686/match.S


ifndef FOSSIL_ENABLE_MINIZ
LIBTARGETS += zlib
endif

openssl:	$(LIBTARGETS)



	cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)

	$(MAKE) -C $(OPENSSLLIBDIR) build_libs

clean-openssl:
	$(MAKE) -C $(OPENSSLLIBDIR) clean

tcl:
	cd $(TCLSRCDIR)/win;./configure
	$(MAKE) -C $(TCLSRCDIR)/win $(TCLTARGET)

clean-tcl:
	$(MAKE) -C $(TCLSRCDIR)/win distclean

APPTARGETS += $(LIBTARGETS)

ifdef FOSSIL_BUILD_SSL
APPTARGETS += openssl
endif

$(APPNAME):	$(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
	$(CODECHECK1) $(TRANS_SRC)
	$(TCC) -o $@ $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o

# 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:
	# noop

836
837
838
839
840
841
842



843
844
845
846
847
848
849
850
851

852
853
854
855
856
857
858

innosetup: $(OBJDIR) $(APPNAME)
	$(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)

$(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
	$(MKINDEX) $(TRANS_SRC) >$@




$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
	$(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
		$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
		$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
		$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
		$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
		$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
		$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
		$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \

		$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
		$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
		$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
		$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
		$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
		$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
		$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \







>
>
>
|








>







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901

innosetup: $(OBJDIR) $(APPNAME)
	$(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)

$(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
	$(MKINDEX) $(TRANS_SRC) >$@

$(OBJDIR)/builtin_data.h:	$(MKBUILTIN) $(EXTRA_FILES)
	$(MKBUILTIN) $(EXTRA_FILES) >$@

$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
	$(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
		$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
		$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
		$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
		$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
		$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
		$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
		$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
		$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
		$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
		$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
		$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
		$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
		$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
		$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
		$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027








1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
	echo Done >$(OBJDIR)/headers

$(OBJDIR)/headers: Makefile

Makefile:

$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c

$(OBJDIR)/add.o:	$(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c

$(OBJDIR)/add.h:	$(OBJDIR)/headers

$(OBJDIR)/allrepo_.c:	$(SRCDIR)/allrepo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/allrepo.c >$(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.o:	$(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.h:	$(OBJDIR)/headers

$(OBJDIR)/attach_.c:	$(SRCDIR)/attach.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/attach.c >$(OBJDIR)/attach_.c

$(OBJDIR)/attach.o:	$(OBJDIR)/attach_.c $(OBJDIR)/attach.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/attach.o -c $(OBJDIR)/attach_.c

$(OBJDIR)/attach.h:	$(OBJDIR)/headers

$(OBJDIR)/bag_.c:	$(SRCDIR)/bag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bag.c >$(OBJDIR)/bag_.c

$(OBJDIR)/bag.o:	$(OBJDIR)/bag_.c $(OBJDIR)/bag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c $(OBJDIR)/bag_.c

$(OBJDIR)/bag.h:	$(OBJDIR)/headers

$(OBJDIR)/bisect_.c:	$(SRCDIR)/bisect.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bisect.c >$(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.o:	$(OBJDIR)/bisect_.c $(OBJDIR)/bisect.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bisect.o -c $(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.h:	$(OBJDIR)/headers

$(OBJDIR)/blob_.c:	$(SRCDIR)/blob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/blob.c >$(OBJDIR)/blob_.c

$(OBJDIR)/blob.o:	$(OBJDIR)/blob_.c $(OBJDIR)/blob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c $(OBJDIR)/blob_.c

$(OBJDIR)/blob.h:	$(OBJDIR)/headers

$(OBJDIR)/branch_.c:	$(SRCDIR)/branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/branch.c >$(OBJDIR)/branch_.c

$(OBJDIR)/branch.o:	$(OBJDIR)/branch_.c $(OBJDIR)/branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c $(OBJDIR)/branch_.c

$(OBJDIR)/branch.h:	$(OBJDIR)/headers

$(OBJDIR)/browse_.c:	$(SRCDIR)/browse.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/browse.c >$(OBJDIR)/browse_.c

$(OBJDIR)/browse.o:	$(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c

$(OBJDIR)/browse.h:	$(OBJDIR)/headers









$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

$(OBJDIR)/cache.h:	$(OBJDIR)/headers

$(OBJDIR)/captcha_.c:	$(SRCDIR)/captcha.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/captcha.c >$(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.o:	$(OBJDIR)/captcha_.c $(OBJDIR)/captcha.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c $(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.h:	$(OBJDIR)/headers

$(OBJDIR)/cgi_.c:	$(SRCDIR)/cgi.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cgi.c >$(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.o:	$(OBJDIR)/cgi_.c $(OBJDIR)/cgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c $(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.h:	$(OBJDIR)/headers

$(OBJDIR)/checkin_.c:	$(SRCDIR)/checkin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkin.c >$(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.o:	$(OBJDIR)/checkin_.c $(OBJDIR)/checkin.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c $(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.h:	$(OBJDIR)/headers

$(OBJDIR)/checkout_.c:	$(SRCDIR)/checkout.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkout.c >$(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.o:	$(OBJDIR)/checkout_.c $(OBJDIR)/checkout.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c $(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.h:	$(OBJDIR)/headers

$(OBJDIR)/clearsign_.c:	$(SRCDIR)/clearsign.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clearsign.c >$(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.o:	$(OBJDIR)/clearsign_.c $(OBJDIR)/clearsign.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c $(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.h:	$(OBJDIR)/headers

$(OBJDIR)/clone_.c:	$(SRCDIR)/clone.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clone.c >$(OBJDIR)/clone_.c

$(OBJDIR)/clone.o:	$(OBJDIR)/clone_.c $(OBJDIR)/clone.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c $(OBJDIR)/clone_.c

$(OBJDIR)/clone.h:	$(OBJDIR)/headers

$(OBJDIR)/comformat_.c:	$(SRCDIR)/comformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/comformat.c >$(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.o:	$(OBJDIR)/comformat_.c $(OBJDIR)/comformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c $(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.h:	$(OBJDIR)/headers

$(OBJDIR)/configure_.c:	$(SRCDIR)/configure.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/configure.c >$(OBJDIR)/configure_.c

$(OBJDIR)/configure.o:	$(OBJDIR)/configure_.c $(OBJDIR)/configure.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c $(OBJDIR)/configure_.c

$(OBJDIR)/configure.h:	$(OBJDIR)/headers

$(OBJDIR)/content_.c:	$(SRCDIR)/content.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/content.c >$(OBJDIR)/content_.c

$(OBJDIR)/content.o:	$(OBJDIR)/content_.c $(OBJDIR)/content.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c $(OBJDIR)/content_.c

$(OBJDIR)/content.h:	$(OBJDIR)/headers

$(OBJDIR)/db_.c:	$(SRCDIR)/db.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/db.c >$(OBJDIR)/db_.c

$(OBJDIR)/db.o:	$(OBJDIR)/db_.c $(OBJDIR)/db.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c $(OBJDIR)/db_.c

$(OBJDIR)/db.h:	$(OBJDIR)/headers

$(OBJDIR)/delta_.c:	$(SRCDIR)/delta.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/delta.c >$(OBJDIR)/delta_.c

$(OBJDIR)/delta.o:	$(OBJDIR)/delta_.c $(OBJDIR)/delta.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c $(OBJDIR)/delta_.c

$(OBJDIR)/delta.h:	$(OBJDIR)/headers

$(OBJDIR)/deltacmd_.c:	$(SRCDIR)/deltacmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/deltacmd.c >$(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.o:	$(OBJDIR)/deltacmd_.c $(OBJDIR)/deltacmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c $(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.h:	$(OBJDIR)/headers

$(OBJDIR)/descendants_.c:	$(SRCDIR)/descendants.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/descendants.c >$(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.o:	$(OBJDIR)/descendants_.c $(OBJDIR)/descendants.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c $(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.h:	$(OBJDIR)/headers

$(OBJDIR)/diff_.c:	$(SRCDIR)/diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diff.c >$(OBJDIR)/diff_.c

$(OBJDIR)/diff.o:	$(OBJDIR)/diff_.c $(OBJDIR)/diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c $(OBJDIR)/diff_.c

$(OBJDIR)/diff.h:	$(OBJDIR)/headers

$(OBJDIR)/diffcmd_.c:	$(SRCDIR)/diffcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diffcmd.c >$(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.o:	$(OBJDIR)/diffcmd_.c $(OBJDIR)/diffcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c $(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/doc_.c:	$(SRCDIR)/doc.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/doc.c >$(OBJDIR)/doc_.c

$(OBJDIR)/doc.o:	$(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c

$(OBJDIR)/doc.h:	$(OBJDIR)/headers

$(OBJDIR)/encode_.c:	$(SRCDIR)/encode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/encode.c >$(OBJDIR)/encode_.c

$(OBJDIR)/encode.o:	$(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c

$(OBJDIR)/encode.h:	$(OBJDIR)/headers

$(OBJDIR)/event_.c:	$(SRCDIR)/event.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/event.c >$(OBJDIR)/event_.c

$(OBJDIR)/event.o:	$(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/event.o -c $(OBJDIR)/event_.c

$(OBJDIR)/event.h:	$(OBJDIR)/headers

$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/export.c >$(OBJDIR)/export_.c

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/file.c >$(OBJDIR)/file_.c

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

$(OBJDIR)/file.h:	$(OBJDIR)/headers

$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.h:	$(OBJDIR)/headers

$(OBJDIR)/glob_.c:	$(SRCDIR)/glob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/glob.c >$(OBJDIR)/glob_.c

$(OBJDIR)/glob.o:	$(OBJDIR)/glob_.c $(OBJDIR)/glob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/glob.o -c $(OBJDIR)/glob_.c

$(OBJDIR)/glob.h:	$(OBJDIR)/headers

$(OBJDIR)/graph_.c:	$(SRCDIR)/graph.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/graph.c >$(OBJDIR)/graph_.c

$(OBJDIR)/graph.o:	$(OBJDIR)/graph_.c $(OBJDIR)/graph.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c $(OBJDIR)/graph_.c

$(OBJDIR)/graph.h:	$(OBJDIR)/headers

$(OBJDIR)/gzip_.c:	$(SRCDIR)/gzip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/gzip.c >$(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.o:	$(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.h:	$(OBJDIR)/headers

$(OBJDIR)/http_.c:	$(SRCDIR)/http.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http.c >$(OBJDIR)/http_.c

$(OBJDIR)/http.o:	$(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c

$(OBJDIR)/http.h:	$(OBJDIR)/headers

$(OBJDIR)/http_socket_.c:	$(SRCDIR)/http_socket.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_socket.c >$(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.o:	$(OBJDIR)/http_socket_.c $(OBJDIR)/http_socket.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c $(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.h:	$(OBJDIR)/headers

$(OBJDIR)/http_ssl_.c:	$(SRCDIR)/http_ssl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_ssl.c >$(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.o:	$(OBJDIR)/http_ssl_.c $(OBJDIR)/http_ssl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_ssl.o -c $(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.h:	$(OBJDIR)/headers

$(OBJDIR)/http_transport_.c:	$(SRCDIR)/http_transport.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_transport.c >$(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.o:	$(OBJDIR)/http_transport_.c $(OBJDIR)/http_transport.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c $(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.h:	$(OBJDIR)/headers

$(OBJDIR)/import_.c:	$(SRCDIR)/import.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/import.c >$(OBJDIR)/import_.c

$(OBJDIR)/import.o:	$(OBJDIR)/import_.c $(OBJDIR)/import.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/import.o -c $(OBJDIR)/import_.c

$(OBJDIR)/import.h:	$(OBJDIR)/headers

$(OBJDIR)/info_.c:	$(SRCDIR)/info.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/info.c >$(OBJDIR)/info_.c

$(OBJDIR)/info.o:	$(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c

$(OBJDIR)/info.h:	$(OBJDIR)/headers

$(OBJDIR)/json_.c:	$(SRCDIR)/json.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json.c >$(OBJDIR)/json_.c

$(OBJDIR)/json.o:	$(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c

$(OBJDIR)/json.h:	$(OBJDIR)/headers

$(OBJDIR)/json_artifact_.c:	$(SRCDIR)/json_artifact.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.o:	$(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.h:	$(OBJDIR)/headers

$(OBJDIR)/json_branch_.c:	$(SRCDIR)/json_branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.o:	$(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.h:	$(OBJDIR)/headers

$(OBJDIR)/json_config_.c:	$(SRCDIR)/json_config.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_config.c >$(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.o:	$(OBJDIR)/json_config_.c $(OBJDIR)/json_config.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_config.o -c $(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.h:	$(OBJDIR)/headers

$(OBJDIR)/json_diff_.c:	$(SRCDIR)/json_diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.o:	$(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.h:	$(OBJDIR)/headers

$(OBJDIR)/json_dir_.c:	$(SRCDIR)/json_dir.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_dir.c >$(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.o:	$(OBJDIR)/json_dir_.c $(OBJDIR)/json_dir.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_dir.o -c $(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.h:	$(OBJDIR)/headers

$(OBJDIR)/json_finfo_.c:	$(SRCDIR)/json_finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_finfo.c >$(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.o:	$(OBJDIR)/json_finfo_.c $(OBJDIR)/json_finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_finfo.o -c $(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/json_login_.c:	$(SRCDIR)/json_login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.o:	$(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.h:	$(OBJDIR)/headers

$(OBJDIR)/json_query_.c:	$(SRCDIR)/json_query.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.o:	$(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.h:	$(OBJDIR)/headers

$(OBJDIR)/json_report_.c:	$(SRCDIR)/json_report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.o:	$(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.h:	$(OBJDIR)/headers

$(OBJDIR)/json_status_.c:	$(SRCDIR)/json_status.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_status.c >$(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.o:	$(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.h:	$(OBJDIR)/headers

$(OBJDIR)/json_tag_.c:	$(SRCDIR)/json_tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.o:	$(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.h:	$(OBJDIR)/headers

$(OBJDIR)/json_timeline_.c:	$(SRCDIR)/json_timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.o:	$(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/json_user_.c:	$(SRCDIR)/json_user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.o:	$(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.h:	$(OBJDIR)/headers

$(OBJDIR)/json_wiki_.c:	$(SRCDIR)/json_wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.o:	$(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/leaf_.c:	$(SRCDIR)/leaf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.o:	$(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.h:	$(OBJDIR)/headers

$(OBJDIR)/loadctrl_.c:	$(SRCDIR)/loadctrl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/loadctrl.c >$(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.o:	$(OBJDIR)/loadctrl_.c $(OBJDIR)/loadctrl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/loadctrl.o -c $(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.h:	$(OBJDIR)/headers

$(OBJDIR)/login_.c:	$(SRCDIR)/login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/login.c >$(OBJDIR)/login_.c

$(OBJDIR)/login.o:	$(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c

$(OBJDIR)/login.h:	$(OBJDIR)/headers

$(OBJDIR)/lookslike_.c:	$(SRCDIR)/lookslike.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.o:	$(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.h:	$(OBJDIR)/headers

$(OBJDIR)/main_.c:	$(SRCDIR)/main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c

$(OBJDIR)/main.o:	$(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c

$(OBJDIR)/main.h:	$(OBJDIR)/headers

$(OBJDIR)/manifest_.c:	$(SRCDIR)/manifest.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/manifest.c >$(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.o:	$(OBJDIR)/manifest_.c $(OBJDIR)/manifest.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c $(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_.c:	$(SRCDIR)/markdown.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown.c >$(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.o:	$(OBJDIR)/markdown_.c $(OBJDIR)/markdown.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown.o -c $(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_html_.c:	$(SRCDIR)/markdown_html.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown_html.c >$(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.o:	$(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.h:	$(OBJDIR)/headers

$(OBJDIR)/md5_.c:	$(SRCDIR)/md5.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/md5.c >$(OBJDIR)/md5_.c

$(OBJDIR)/md5.o:	$(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c

$(OBJDIR)/md5.h:	$(OBJDIR)/headers

$(OBJDIR)/merge_.c:	$(SRCDIR)/merge.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge.c >$(OBJDIR)/merge_.c

$(OBJDIR)/merge.o:	$(OBJDIR)/merge_.c $(OBJDIR)/merge.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c $(OBJDIR)/merge_.c

$(OBJDIR)/merge.h:	$(OBJDIR)/headers

$(OBJDIR)/merge3_.c:	$(SRCDIR)/merge3.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge3.c >$(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.o:	$(OBJDIR)/merge3_.c $(OBJDIR)/merge3.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c $(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.h:	$(OBJDIR)/headers

$(OBJDIR)/moderate_.c:	$(SRCDIR)/moderate.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/moderate.c >$(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.o:	$(OBJDIR)/moderate_.c $(OBJDIR)/moderate.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/moderate.o -c $(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.h:	$(OBJDIR)/headers

$(OBJDIR)/name_.c:	$(SRCDIR)/name.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/name.c >$(OBJDIR)/name_.c

$(OBJDIR)/name.o:	$(OBJDIR)/name_.c $(OBJDIR)/name.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c $(OBJDIR)/name_.c

$(OBJDIR)/name.h:	$(OBJDIR)/headers

$(OBJDIR)/path_.c:	$(SRCDIR)/path.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/path.c >$(OBJDIR)/path_.c

$(OBJDIR)/path.o:	$(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c

$(OBJDIR)/path.h:	$(OBJDIR)/headers

$(OBJDIR)/pivot_.c:	$(SRCDIR)/pivot.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pivot.c >$(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.o:	$(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.h:	$(OBJDIR)/headers

$(OBJDIR)/popen_.c:	$(SRCDIR)/popen.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/popen.c >$(OBJDIR)/popen_.c

$(OBJDIR)/popen.o:	$(OBJDIR)/popen_.c $(OBJDIR)/popen.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/popen.o -c $(OBJDIR)/popen_.c

$(OBJDIR)/popen.h:	$(OBJDIR)/headers

$(OBJDIR)/pqueue_.c:	$(SRCDIR)/pqueue.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pqueue.c >$(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.o:	$(OBJDIR)/pqueue_.c $(OBJDIR)/pqueue.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c $(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.h:	$(OBJDIR)/headers

$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/printf.c >$(OBJDIR)/printf_.c

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rebuild.c >$(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.h:	$(OBJDIR)/headers

$(OBJDIR)/regexp_.c:	$(SRCDIR)/regexp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.o:	$(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.h:	$(OBJDIR)/headers

$(OBJDIR)/report_.c:	$(SRCDIR)/report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c

$(OBJDIR)/report.o:	$(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c

$(OBJDIR)/report.h:	$(OBJDIR)/headers

$(OBJDIR)/rss_.c:	$(SRCDIR)/rss.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rss.c >$(OBJDIR)/rss_.c

$(OBJDIR)/rss.o:	$(OBJDIR)/rss_.c $(OBJDIR)/rss.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c $(OBJDIR)/rss_.c

$(OBJDIR)/rss.h:	$(OBJDIR)/headers

$(OBJDIR)/schema_.c:	$(SRCDIR)/schema.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/schema.c >$(OBJDIR)/schema_.c

$(OBJDIR)/schema.o:	$(OBJDIR)/schema_.c $(OBJDIR)/schema.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c $(OBJDIR)/schema_.c

$(OBJDIR)/schema.h:	$(OBJDIR)/headers

$(OBJDIR)/search_.c:	$(SRCDIR)/search.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/search.c >$(OBJDIR)/search_.c

$(OBJDIR)/search.o:	$(OBJDIR)/search_.c $(OBJDIR)/search.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c $(OBJDIR)/search_.c

$(OBJDIR)/search.h:	$(OBJDIR)/headers

$(OBJDIR)/setup_.c:	$(SRCDIR)/setup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/setup.c >$(OBJDIR)/setup_.c

$(OBJDIR)/setup.o:	$(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c

$(OBJDIR)/setup.h:	$(OBJDIR)/headers

$(OBJDIR)/sha1_.c:	$(SRCDIR)/sha1.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sha1.c >$(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.o:	$(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.h:	$(OBJDIR)/headers

$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$(OBJDIR)/shun_.c

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$(OBJDIR)/skins_.c

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

$(OBJDIR)/skins.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlcmd_.c:	$(SRCDIR)/sqlcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sqlcmd.c >$(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.o:	$(OBJDIR)/sqlcmd_.c $(OBJDIR)/sqlcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sqlcmd.o -c $(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/stash_.c:	$(SRCDIR)/stash.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stash.c >$(OBJDIR)/stash_.c

$(OBJDIR)/stash.o:	$(OBJDIR)/stash_.c $(OBJDIR)/stash.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stash.o -c $(OBJDIR)/stash_.c

$(OBJDIR)/stash.h:	$(OBJDIR)/headers

$(OBJDIR)/stat_.c:	$(SRCDIR)/stat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stat.c >$(OBJDIR)/stat_.c

$(OBJDIR)/stat.o:	$(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c

$(OBJDIR)/stat.h:	$(OBJDIR)/headers

$(OBJDIR)/style_.c:	$(SRCDIR)/style.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/style.c >$(OBJDIR)/style_.c

$(OBJDIR)/style.o:	$(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c $(OBJDIR)/style_.c

$(OBJDIR)/style.h:	$(OBJDIR)/headers

$(OBJDIR)/sync_.c:	$(SRCDIR)/sync.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sync.c >$(OBJDIR)/sync_.c

$(OBJDIR)/sync.o:	$(OBJDIR)/sync_.c $(OBJDIR)/sync.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c $(OBJDIR)/sync_.c

$(OBJDIR)/sync.h:	$(OBJDIR)/headers

$(OBJDIR)/tag_.c:	$(SRCDIR)/tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tag.c >$(OBJDIR)/tag_.c

$(OBJDIR)/tag.o:	$(OBJDIR)/tag_.c $(OBJDIR)/tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c $(OBJDIR)/tag_.c

$(OBJDIR)/tag.h:	$(OBJDIR)/headers

$(OBJDIR)/tar_.c:	$(SRCDIR)/tar.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tar.c >$(OBJDIR)/tar_.c

$(OBJDIR)/tar.o:	$(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c

$(OBJDIR)/tar.h:	$(OBJDIR)/headers

$(OBJDIR)/th_main_.c:	$(SRCDIR)/th_main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/th_main.c >$(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.o:	$(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.h:	$(OBJDIR)/headers

$(OBJDIR)/timeline_.c:	$(SRCDIR)/timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/timeline.c >$(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.o:	$(OBJDIR)/timeline_.c $(OBJDIR)/timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c $(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/tkt_.c:	$(SRCDIR)/tkt.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tkt.c >$(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.o:	$(OBJDIR)/tkt_.c $(OBJDIR)/tkt.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c $(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.h:	$(OBJDIR)/headers

$(OBJDIR)/tktsetup_.c:	$(SRCDIR)/tktsetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tktsetup.c >$(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.o:	$(OBJDIR)/tktsetup_.c $(OBJDIR)/tktsetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c $(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.h:	$(OBJDIR)/headers

$(OBJDIR)/undo_.c:	$(SRCDIR)/undo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/undo.c >$(OBJDIR)/undo_.c

$(OBJDIR)/undo.o:	$(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c

$(OBJDIR)/undo.h:	$(OBJDIR)/headers

$(OBJDIR)/unicode_.c:	$(SRCDIR)/unicode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.o:	$(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.h:	$(OBJDIR)/headers

$(OBJDIR)/update_.c:	$(SRCDIR)/update.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c

$(OBJDIR)/update.o:	$(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c

$(OBJDIR)/update.h:	$(OBJDIR)/headers

$(OBJDIR)/url_.c:	$(SRCDIR)/url.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/url.c >$(OBJDIR)/url_.c

$(OBJDIR)/url.o:	$(OBJDIR)/url_.c $(OBJDIR)/url.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c $(OBJDIR)/url_.c

$(OBJDIR)/url.h:	$(OBJDIR)/headers

$(OBJDIR)/user_.c:	$(SRCDIR)/user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/user.c >$(OBJDIR)/user_.c

$(OBJDIR)/user.o:	$(OBJDIR)/user_.c $(OBJDIR)/user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c $(OBJDIR)/user_.c

$(OBJDIR)/user.h:	$(OBJDIR)/headers

$(OBJDIR)/utf8_.c:	$(SRCDIR)/utf8.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/utf8.c >$(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.o:	$(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.h:	$(OBJDIR)/headers

$(OBJDIR)/util_.c:	$(SRCDIR)/util.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/util.c >$(OBJDIR)/util_.c

$(OBJDIR)/util.o:	$(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c

$(OBJDIR)/util.h:	$(OBJDIR)/headers

$(OBJDIR)/verify_.c:	$(SRCDIR)/verify.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/verify.c >$(OBJDIR)/verify_.c

$(OBJDIR)/verify.o:	$(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c $(OBJDIR)/verify_.c

$(OBJDIR)/verify.h:	$(OBJDIR)/headers

$(OBJDIR)/vfile_.c:	$(SRCDIR)/vfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/vfile.c >$(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.o:	$(OBJDIR)/vfile_.c $(OBJDIR)/vfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c $(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.h:	$(OBJDIR)/headers

$(OBJDIR)/wiki_.c:	$(SRCDIR)/wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wiki.c >$(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.o:	$(OBJDIR)/wiki_.c $(OBJDIR)/wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c $(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/wikiformat_.c:	$(SRCDIR)/wikiformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wikiformat.c >$(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.o:	$(OBJDIR)/wikiformat_.c $(OBJDIR)/wikiformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c $(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.h:	$(OBJDIR)/headers

$(OBJDIR)/winfile_.c:	$(SRCDIR)/winfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winfile.c >$(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.o:	$(OBJDIR)/winfile_.c $(OBJDIR)/winfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winfile.o -c $(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.h:	$(OBJDIR)/headers

$(OBJDIR)/winhttp_.c:	$(SRCDIR)/winhttp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winhttp.c >$(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.o:	$(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.h:	$(OBJDIR)/headers

$(OBJDIR)/wysiwyg_.c:	$(SRCDIR)/wysiwyg.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wysiwyg.c >$(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.o:	$(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.h:	$(OBJDIR)/headers

$(OBJDIR)/xfer_.c:	$(SRCDIR)/xfer.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfer.c >$(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.o:	$(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.h:	$(OBJDIR)/headers

$(OBJDIR)/xfersetup_.c:	$(SRCDIR)/xfersetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfersetup.c >$(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.o:	$(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.h:	$(OBJDIR)/headers

$(OBJDIR)/zip_.c:	$(SRCDIR)/zip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/zip.c >$(OBJDIR)/zip_.c

$(OBJDIR)/zip.o:	$(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers

SQLITE_OPTIONS = -DNDEBUG=1 \







|







|







|







|







|







|







|







|






>
>
>
>
>
>
>
>

|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







|







1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
	echo Done >$(OBJDIR)/headers

$(OBJDIR)/headers: Makefile

Makefile:

$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/add.c >$@

$(OBJDIR)/add.o:	$(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c

$(OBJDIR)/add.h:	$(OBJDIR)/headers

$(OBJDIR)/allrepo_.c:	$(SRCDIR)/allrepo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/allrepo.c >$@

$(OBJDIR)/allrepo.o:	$(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.h:	$(OBJDIR)/headers

$(OBJDIR)/attach_.c:	$(SRCDIR)/attach.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/attach.c >$@

$(OBJDIR)/attach.o:	$(OBJDIR)/attach_.c $(OBJDIR)/attach.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/attach.o -c $(OBJDIR)/attach_.c

$(OBJDIR)/attach.h:	$(OBJDIR)/headers

$(OBJDIR)/bag_.c:	$(SRCDIR)/bag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bag.c >$@

$(OBJDIR)/bag.o:	$(OBJDIR)/bag_.c $(OBJDIR)/bag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c $(OBJDIR)/bag_.c

$(OBJDIR)/bag.h:	$(OBJDIR)/headers

$(OBJDIR)/bisect_.c:	$(SRCDIR)/bisect.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bisect.c >$@

$(OBJDIR)/bisect.o:	$(OBJDIR)/bisect_.c $(OBJDIR)/bisect.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bisect.o -c $(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.h:	$(OBJDIR)/headers

$(OBJDIR)/blob_.c:	$(SRCDIR)/blob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/blob.c >$@

$(OBJDIR)/blob.o:	$(OBJDIR)/blob_.c $(OBJDIR)/blob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c $(OBJDIR)/blob_.c

$(OBJDIR)/blob.h:	$(OBJDIR)/headers

$(OBJDIR)/branch_.c:	$(SRCDIR)/branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/branch.c >$@

$(OBJDIR)/branch.o:	$(OBJDIR)/branch_.c $(OBJDIR)/branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c $(OBJDIR)/branch_.c

$(OBJDIR)/branch.h:	$(OBJDIR)/headers

$(OBJDIR)/browse_.c:	$(SRCDIR)/browse.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/browse.c >$@

$(OBJDIR)/browse.o:	$(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c

$(OBJDIR)/browse.h:	$(OBJDIR)/headers

$(OBJDIR)/builtin_.c:	$(SRCDIR)/builtin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/builtin.c >$@

$(OBJDIR)/builtin.o:	$(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c

$(OBJDIR)/builtin.h:	$(OBJDIR)/headers

$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cache.c >$@

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

$(OBJDIR)/cache.h:	$(OBJDIR)/headers

$(OBJDIR)/captcha_.c:	$(SRCDIR)/captcha.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/captcha.c >$@

$(OBJDIR)/captcha.o:	$(OBJDIR)/captcha_.c $(OBJDIR)/captcha.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c $(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.h:	$(OBJDIR)/headers

$(OBJDIR)/cgi_.c:	$(SRCDIR)/cgi.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cgi.c >$@

$(OBJDIR)/cgi.o:	$(OBJDIR)/cgi_.c $(OBJDIR)/cgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c $(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.h:	$(OBJDIR)/headers

$(OBJDIR)/checkin_.c:	$(SRCDIR)/checkin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkin.c >$@

$(OBJDIR)/checkin.o:	$(OBJDIR)/checkin_.c $(OBJDIR)/checkin.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c $(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.h:	$(OBJDIR)/headers

$(OBJDIR)/checkout_.c:	$(SRCDIR)/checkout.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/checkout.c >$@

$(OBJDIR)/checkout.o:	$(OBJDIR)/checkout_.c $(OBJDIR)/checkout.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c $(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.h:	$(OBJDIR)/headers

$(OBJDIR)/clearsign_.c:	$(SRCDIR)/clearsign.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clearsign.c >$@

$(OBJDIR)/clearsign.o:	$(OBJDIR)/clearsign_.c $(OBJDIR)/clearsign.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c $(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.h:	$(OBJDIR)/headers

$(OBJDIR)/clone_.c:	$(SRCDIR)/clone.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/clone.c >$@

$(OBJDIR)/clone.o:	$(OBJDIR)/clone_.c $(OBJDIR)/clone.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c $(OBJDIR)/clone_.c

$(OBJDIR)/clone.h:	$(OBJDIR)/headers

$(OBJDIR)/comformat_.c:	$(SRCDIR)/comformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/comformat.c >$@

$(OBJDIR)/comformat.o:	$(OBJDIR)/comformat_.c $(OBJDIR)/comformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c $(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.h:	$(OBJDIR)/headers

$(OBJDIR)/configure_.c:	$(SRCDIR)/configure.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/configure.c >$@

$(OBJDIR)/configure.o:	$(OBJDIR)/configure_.c $(OBJDIR)/configure.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c $(OBJDIR)/configure_.c

$(OBJDIR)/configure.h:	$(OBJDIR)/headers

$(OBJDIR)/content_.c:	$(SRCDIR)/content.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/content.c >$@

$(OBJDIR)/content.o:	$(OBJDIR)/content_.c $(OBJDIR)/content.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c $(OBJDIR)/content_.c

$(OBJDIR)/content.h:	$(OBJDIR)/headers

$(OBJDIR)/db_.c:	$(SRCDIR)/db.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/db.c >$@

$(OBJDIR)/db.o:	$(OBJDIR)/db_.c $(OBJDIR)/db.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c $(OBJDIR)/db_.c

$(OBJDIR)/db.h:	$(OBJDIR)/headers

$(OBJDIR)/delta_.c:	$(SRCDIR)/delta.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/delta.c >$@

$(OBJDIR)/delta.o:	$(OBJDIR)/delta_.c $(OBJDIR)/delta.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c $(OBJDIR)/delta_.c

$(OBJDIR)/delta.h:	$(OBJDIR)/headers

$(OBJDIR)/deltacmd_.c:	$(SRCDIR)/deltacmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/deltacmd.c >$@

$(OBJDIR)/deltacmd.o:	$(OBJDIR)/deltacmd_.c $(OBJDIR)/deltacmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c $(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.h:	$(OBJDIR)/headers

$(OBJDIR)/descendants_.c:	$(SRCDIR)/descendants.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/descendants.c >$@

$(OBJDIR)/descendants.o:	$(OBJDIR)/descendants_.c $(OBJDIR)/descendants.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c $(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.h:	$(OBJDIR)/headers

$(OBJDIR)/diff_.c:	$(SRCDIR)/diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diff.c >$@

$(OBJDIR)/diff.o:	$(OBJDIR)/diff_.c $(OBJDIR)/diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c $(OBJDIR)/diff_.c

$(OBJDIR)/diff.h:	$(OBJDIR)/headers

$(OBJDIR)/diffcmd_.c:	$(SRCDIR)/diffcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/diffcmd.c >$@

$(OBJDIR)/diffcmd.o:	$(OBJDIR)/diffcmd_.c $(OBJDIR)/diffcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c $(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/doc_.c:	$(SRCDIR)/doc.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/doc.c >$@

$(OBJDIR)/doc.o:	$(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c

$(OBJDIR)/doc.h:	$(OBJDIR)/headers

$(OBJDIR)/encode_.c:	$(SRCDIR)/encode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/encode.c >$@

$(OBJDIR)/encode.o:	$(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c

$(OBJDIR)/encode.h:	$(OBJDIR)/headers

$(OBJDIR)/event_.c:	$(SRCDIR)/event.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/event.c >$@

$(OBJDIR)/event.o:	$(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/event.o -c $(OBJDIR)/event_.c

$(OBJDIR)/event.h:	$(OBJDIR)/headers

$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/export.c >$@

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/file.c >$@

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

$(OBJDIR)/file.h:	$(OBJDIR)/headers

$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$@

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

$(OBJDIR)/fusefs.h:	$(OBJDIR)/headers

$(OBJDIR)/glob_.c:	$(SRCDIR)/glob.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/glob.c >$@

$(OBJDIR)/glob.o:	$(OBJDIR)/glob_.c $(OBJDIR)/glob.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/glob.o -c $(OBJDIR)/glob_.c

$(OBJDIR)/glob.h:	$(OBJDIR)/headers

$(OBJDIR)/graph_.c:	$(SRCDIR)/graph.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/graph.c >$@

$(OBJDIR)/graph.o:	$(OBJDIR)/graph_.c $(OBJDIR)/graph.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c $(OBJDIR)/graph_.c

$(OBJDIR)/graph.h:	$(OBJDIR)/headers

$(OBJDIR)/gzip_.c:	$(SRCDIR)/gzip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/gzip.c >$@

$(OBJDIR)/gzip.o:	$(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.h:	$(OBJDIR)/headers

$(OBJDIR)/http_.c:	$(SRCDIR)/http.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http.c >$@

$(OBJDIR)/http.o:	$(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c

$(OBJDIR)/http.h:	$(OBJDIR)/headers

$(OBJDIR)/http_socket_.c:	$(SRCDIR)/http_socket.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_socket.c >$@

$(OBJDIR)/http_socket.o:	$(OBJDIR)/http_socket_.c $(OBJDIR)/http_socket.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c $(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.h:	$(OBJDIR)/headers

$(OBJDIR)/http_ssl_.c:	$(SRCDIR)/http_ssl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_ssl.c >$@

$(OBJDIR)/http_ssl.o:	$(OBJDIR)/http_ssl_.c $(OBJDIR)/http_ssl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_ssl.o -c $(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.h:	$(OBJDIR)/headers

$(OBJDIR)/http_transport_.c:	$(SRCDIR)/http_transport.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/http_transport.c >$@

$(OBJDIR)/http_transport.o:	$(OBJDIR)/http_transport_.c $(OBJDIR)/http_transport.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c $(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.h:	$(OBJDIR)/headers

$(OBJDIR)/import_.c:	$(SRCDIR)/import.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/import.c >$@

$(OBJDIR)/import.o:	$(OBJDIR)/import_.c $(OBJDIR)/import.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/import.o -c $(OBJDIR)/import_.c

$(OBJDIR)/import.h:	$(OBJDIR)/headers

$(OBJDIR)/info_.c:	$(SRCDIR)/info.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/info.c >$@

$(OBJDIR)/info.o:	$(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c

$(OBJDIR)/info.h:	$(OBJDIR)/headers

$(OBJDIR)/json_.c:	$(SRCDIR)/json.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json.c >$@

$(OBJDIR)/json.o:	$(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c

$(OBJDIR)/json.h:	$(OBJDIR)/headers

$(OBJDIR)/json_artifact_.c:	$(SRCDIR)/json_artifact.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_artifact.c >$@

$(OBJDIR)/json_artifact.o:	$(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c

$(OBJDIR)/json_artifact.h:	$(OBJDIR)/headers

$(OBJDIR)/json_branch_.c:	$(SRCDIR)/json_branch.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_branch.c >$@

$(OBJDIR)/json_branch.o:	$(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c

$(OBJDIR)/json_branch.h:	$(OBJDIR)/headers

$(OBJDIR)/json_config_.c:	$(SRCDIR)/json_config.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_config.c >$@

$(OBJDIR)/json_config.o:	$(OBJDIR)/json_config_.c $(OBJDIR)/json_config.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_config.o -c $(OBJDIR)/json_config_.c

$(OBJDIR)/json_config.h:	$(OBJDIR)/headers

$(OBJDIR)/json_diff_.c:	$(SRCDIR)/json_diff.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_diff.c >$@

$(OBJDIR)/json_diff.o:	$(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c

$(OBJDIR)/json_diff.h:	$(OBJDIR)/headers

$(OBJDIR)/json_dir_.c:	$(SRCDIR)/json_dir.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_dir.c >$@

$(OBJDIR)/json_dir.o:	$(OBJDIR)/json_dir_.c $(OBJDIR)/json_dir.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_dir.o -c $(OBJDIR)/json_dir_.c

$(OBJDIR)/json_dir.h:	$(OBJDIR)/headers

$(OBJDIR)/json_finfo_.c:	$(SRCDIR)/json_finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_finfo.c >$@

$(OBJDIR)/json_finfo.o:	$(OBJDIR)/json_finfo_.c $(OBJDIR)/json_finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_finfo.o -c $(OBJDIR)/json_finfo_.c

$(OBJDIR)/json_finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/json_login_.c:	$(SRCDIR)/json_login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_login.c >$@

$(OBJDIR)/json_login.o:	$(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c

$(OBJDIR)/json_login.h:	$(OBJDIR)/headers

$(OBJDIR)/json_query_.c:	$(SRCDIR)/json_query.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_query.c >$@

$(OBJDIR)/json_query.o:	$(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c

$(OBJDIR)/json_query.h:	$(OBJDIR)/headers

$(OBJDIR)/json_report_.c:	$(SRCDIR)/json_report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_report.c >$@

$(OBJDIR)/json_report.o:	$(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c

$(OBJDIR)/json_report.h:	$(OBJDIR)/headers

$(OBJDIR)/json_status_.c:	$(SRCDIR)/json_status.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_status.c >$@

$(OBJDIR)/json_status.o:	$(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c

$(OBJDIR)/json_status.h:	$(OBJDIR)/headers

$(OBJDIR)/json_tag_.c:	$(SRCDIR)/json_tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_tag.c >$@

$(OBJDIR)/json_tag.o:	$(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c

$(OBJDIR)/json_tag.h:	$(OBJDIR)/headers

$(OBJDIR)/json_timeline_.c:	$(SRCDIR)/json_timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_timeline.c >$@

$(OBJDIR)/json_timeline.o:	$(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c

$(OBJDIR)/json_timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/json_user_.c:	$(SRCDIR)/json_user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_user.c >$@

$(OBJDIR)/json_user.o:	$(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c

$(OBJDIR)/json_user.h:	$(OBJDIR)/headers

$(OBJDIR)/json_wiki_.c:	$(SRCDIR)/json_wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/json_wiki.c >$@

$(OBJDIR)/json_wiki.o:	$(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c

$(OBJDIR)/json_wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/leaf_.c:	$(SRCDIR)/leaf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/leaf.c >$@

$(OBJDIR)/leaf.o:	$(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.h:	$(OBJDIR)/headers

$(OBJDIR)/loadctrl_.c:	$(SRCDIR)/loadctrl.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/loadctrl.c >$@

$(OBJDIR)/loadctrl.o:	$(OBJDIR)/loadctrl_.c $(OBJDIR)/loadctrl.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/loadctrl.o -c $(OBJDIR)/loadctrl_.c

$(OBJDIR)/loadctrl.h:	$(OBJDIR)/headers

$(OBJDIR)/login_.c:	$(SRCDIR)/login.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/login.c >$@

$(OBJDIR)/login.o:	$(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c

$(OBJDIR)/login.h:	$(OBJDIR)/headers

$(OBJDIR)/lookslike_.c:	$(SRCDIR)/lookslike.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/lookslike.c >$@

$(OBJDIR)/lookslike.o:	$(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c

$(OBJDIR)/lookslike.h:	$(OBJDIR)/headers

$(OBJDIR)/main_.c:	$(SRCDIR)/main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/main.c >$@

$(OBJDIR)/main.o:	$(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c

$(OBJDIR)/main.h:	$(OBJDIR)/headers

$(OBJDIR)/manifest_.c:	$(SRCDIR)/manifest.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/manifest.c >$@

$(OBJDIR)/manifest.o:	$(OBJDIR)/manifest_.c $(OBJDIR)/manifest.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c $(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_.c:	$(SRCDIR)/markdown.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown.c >$@

$(OBJDIR)/markdown.o:	$(OBJDIR)/markdown_.c $(OBJDIR)/markdown.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown.o -c $(OBJDIR)/markdown_.c

$(OBJDIR)/markdown.h:	$(OBJDIR)/headers

$(OBJDIR)/markdown_html_.c:	$(SRCDIR)/markdown_html.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/markdown_html.c >$@

$(OBJDIR)/markdown_html.o:	$(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c

$(OBJDIR)/markdown_html.h:	$(OBJDIR)/headers

$(OBJDIR)/md5_.c:	$(SRCDIR)/md5.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/md5.c >$@

$(OBJDIR)/md5.o:	$(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c

$(OBJDIR)/md5.h:	$(OBJDIR)/headers

$(OBJDIR)/merge_.c:	$(SRCDIR)/merge.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge.c >$@

$(OBJDIR)/merge.o:	$(OBJDIR)/merge_.c $(OBJDIR)/merge.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c $(OBJDIR)/merge_.c

$(OBJDIR)/merge.h:	$(OBJDIR)/headers

$(OBJDIR)/merge3_.c:	$(SRCDIR)/merge3.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/merge3.c >$@

$(OBJDIR)/merge3.o:	$(OBJDIR)/merge3_.c $(OBJDIR)/merge3.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c $(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.h:	$(OBJDIR)/headers

$(OBJDIR)/moderate_.c:	$(SRCDIR)/moderate.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/moderate.c >$@

$(OBJDIR)/moderate.o:	$(OBJDIR)/moderate_.c $(OBJDIR)/moderate.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/moderate.o -c $(OBJDIR)/moderate_.c

$(OBJDIR)/moderate.h:	$(OBJDIR)/headers

$(OBJDIR)/name_.c:	$(SRCDIR)/name.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/name.c >$@

$(OBJDIR)/name.o:	$(OBJDIR)/name_.c $(OBJDIR)/name.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c $(OBJDIR)/name_.c

$(OBJDIR)/name.h:	$(OBJDIR)/headers

$(OBJDIR)/path_.c:	$(SRCDIR)/path.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/path.c >$@

$(OBJDIR)/path.o:	$(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c

$(OBJDIR)/path.h:	$(OBJDIR)/headers

$(OBJDIR)/pivot_.c:	$(SRCDIR)/pivot.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pivot.c >$@

$(OBJDIR)/pivot.o:	$(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.h:	$(OBJDIR)/headers

$(OBJDIR)/popen_.c:	$(SRCDIR)/popen.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/popen.c >$@

$(OBJDIR)/popen.o:	$(OBJDIR)/popen_.c $(OBJDIR)/popen.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/popen.o -c $(OBJDIR)/popen_.c

$(OBJDIR)/popen.h:	$(OBJDIR)/headers

$(OBJDIR)/pqueue_.c:	$(SRCDIR)/pqueue.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/pqueue.c >$@

$(OBJDIR)/pqueue.o:	$(OBJDIR)/pqueue_.c $(OBJDIR)/pqueue.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c $(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.h:	$(OBJDIR)/headers

$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/printf.c >$@

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rebuild.c >$@

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.h:	$(OBJDIR)/headers

$(OBJDIR)/regexp_.c:	$(SRCDIR)/regexp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/regexp.c >$@

$(OBJDIR)/regexp.o:	$(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c

$(OBJDIR)/regexp.h:	$(OBJDIR)/headers

$(OBJDIR)/report_.c:	$(SRCDIR)/report.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/report.c >$@

$(OBJDIR)/report.o:	$(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c

$(OBJDIR)/report.h:	$(OBJDIR)/headers

$(OBJDIR)/rss_.c:	$(SRCDIR)/rss.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rss.c >$@

$(OBJDIR)/rss.o:	$(OBJDIR)/rss_.c $(OBJDIR)/rss.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c $(OBJDIR)/rss_.c

$(OBJDIR)/rss.h:	$(OBJDIR)/headers

$(OBJDIR)/schema_.c:	$(SRCDIR)/schema.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/schema.c >$@

$(OBJDIR)/schema.o:	$(OBJDIR)/schema_.c $(OBJDIR)/schema.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c $(OBJDIR)/schema_.c

$(OBJDIR)/schema.h:	$(OBJDIR)/headers

$(OBJDIR)/search_.c:	$(SRCDIR)/search.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/search.c >$@

$(OBJDIR)/search.o:	$(OBJDIR)/search_.c $(OBJDIR)/search.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c $(OBJDIR)/search_.c

$(OBJDIR)/search.h:	$(OBJDIR)/headers

$(OBJDIR)/setup_.c:	$(SRCDIR)/setup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/setup.c >$@

$(OBJDIR)/setup.o:	$(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c

$(OBJDIR)/setup.h:	$(OBJDIR)/headers

$(OBJDIR)/sha1_.c:	$(SRCDIR)/sha1.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sha1.c >$@

$(OBJDIR)/sha1.o:	$(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.h:	$(OBJDIR)/headers

$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

$(OBJDIR)/skins.h:	$(OBJDIR)/headers

$(OBJDIR)/sqlcmd_.c:	$(SRCDIR)/sqlcmd.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sqlcmd.c >$@

$(OBJDIR)/sqlcmd.o:	$(OBJDIR)/sqlcmd_.c $(OBJDIR)/sqlcmd.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sqlcmd.o -c $(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.h:	$(OBJDIR)/headers

$(OBJDIR)/stash_.c:	$(SRCDIR)/stash.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stash.c >$@

$(OBJDIR)/stash.o:	$(OBJDIR)/stash_.c $(OBJDIR)/stash.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stash.o -c $(OBJDIR)/stash_.c

$(OBJDIR)/stash.h:	$(OBJDIR)/headers

$(OBJDIR)/stat_.c:	$(SRCDIR)/stat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/stat.c >$@

$(OBJDIR)/stat.o:	$(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c

$(OBJDIR)/stat.h:	$(OBJDIR)/headers

$(OBJDIR)/style_.c:	$(SRCDIR)/style.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/style.c >$@

$(OBJDIR)/style.o:	$(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c $(OBJDIR)/style_.c

$(OBJDIR)/style.h:	$(OBJDIR)/headers

$(OBJDIR)/sync_.c:	$(SRCDIR)/sync.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sync.c >$@

$(OBJDIR)/sync.o:	$(OBJDIR)/sync_.c $(OBJDIR)/sync.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c $(OBJDIR)/sync_.c

$(OBJDIR)/sync.h:	$(OBJDIR)/headers

$(OBJDIR)/tag_.c:	$(SRCDIR)/tag.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tag.c >$@

$(OBJDIR)/tag.o:	$(OBJDIR)/tag_.c $(OBJDIR)/tag.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c $(OBJDIR)/tag_.c

$(OBJDIR)/tag.h:	$(OBJDIR)/headers

$(OBJDIR)/tar_.c:	$(SRCDIR)/tar.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tar.c >$@

$(OBJDIR)/tar.o:	$(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c

$(OBJDIR)/tar.h:	$(OBJDIR)/headers

$(OBJDIR)/th_main_.c:	$(SRCDIR)/th_main.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/th_main.c >$@

$(OBJDIR)/th_main.o:	$(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.h:	$(OBJDIR)/headers

$(OBJDIR)/timeline_.c:	$(SRCDIR)/timeline.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/timeline.c >$@

$(OBJDIR)/timeline.o:	$(OBJDIR)/timeline_.c $(OBJDIR)/timeline.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c $(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.h:	$(OBJDIR)/headers

$(OBJDIR)/tkt_.c:	$(SRCDIR)/tkt.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tkt.c >$@

$(OBJDIR)/tkt.o:	$(OBJDIR)/tkt_.c $(OBJDIR)/tkt.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c $(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.h:	$(OBJDIR)/headers

$(OBJDIR)/tktsetup_.c:	$(SRCDIR)/tktsetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/tktsetup.c >$@

$(OBJDIR)/tktsetup.o:	$(OBJDIR)/tktsetup_.c $(OBJDIR)/tktsetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c $(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.h:	$(OBJDIR)/headers

$(OBJDIR)/undo_.c:	$(SRCDIR)/undo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/undo.c >$@

$(OBJDIR)/undo.o:	$(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c

$(OBJDIR)/undo.h:	$(OBJDIR)/headers

$(OBJDIR)/unicode_.c:	$(SRCDIR)/unicode.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/unicode.c >$@

$(OBJDIR)/unicode.o:	$(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c

$(OBJDIR)/unicode.h:	$(OBJDIR)/headers

$(OBJDIR)/update_.c:	$(SRCDIR)/update.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/update.c >$@

$(OBJDIR)/update.o:	$(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c

$(OBJDIR)/update.h:	$(OBJDIR)/headers

$(OBJDIR)/url_.c:	$(SRCDIR)/url.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/url.c >$@

$(OBJDIR)/url.o:	$(OBJDIR)/url_.c $(OBJDIR)/url.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c $(OBJDIR)/url_.c

$(OBJDIR)/url.h:	$(OBJDIR)/headers

$(OBJDIR)/user_.c:	$(SRCDIR)/user.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/user.c >$@

$(OBJDIR)/user.o:	$(OBJDIR)/user_.c $(OBJDIR)/user.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c $(OBJDIR)/user_.c

$(OBJDIR)/user.h:	$(OBJDIR)/headers

$(OBJDIR)/utf8_.c:	$(SRCDIR)/utf8.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/utf8.c >$@

$(OBJDIR)/utf8.o:	$(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c

$(OBJDIR)/utf8.h:	$(OBJDIR)/headers

$(OBJDIR)/util_.c:	$(SRCDIR)/util.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/util.c >$@

$(OBJDIR)/util.o:	$(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c

$(OBJDIR)/util.h:	$(OBJDIR)/headers

$(OBJDIR)/verify_.c:	$(SRCDIR)/verify.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/verify.c >$@

$(OBJDIR)/verify.o:	$(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c $(OBJDIR)/verify_.c

$(OBJDIR)/verify.h:	$(OBJDIR)/headers

$(OBJDIR)/vfile_.c:	$(SRCDIR)/vfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/vfile.c >$@

$(OBJDIR)/vfile.o:	$(OBJDIR)/vfile_.c $(OBJDIR)/vfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c $(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.h:	$(OBJDIR)/headers

$(OBJDIR)/wiki_.c:	$(SRCDIR)/wiki.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wiki.c >$@

$(OBJDIR)/wiki.o:	$(OBJDIR)/wiki_.c $(OBJDIR)/wiki.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c $(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.h:	$(OBJDIR)/headers

$(OBJDIR)/wikiformat_.c:	$(SRCDIR)/wikiformat.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wikiformat.c >$@

$(OBJDIR)/wikiformat.o:	$(OBJDIR)/wikiformat_.c $(OBJDIR)/wikiformat.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c $(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.h:	$(OBJDIR)/headers

$(OBJDIR)/winfile_.c:	$(SRCDIR)/winfile.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winfile.c >$@

$(OBJDIR)/winfile.o:	$(OBJDIR)/winfile_.c $(OBJDIR)/winfile.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winfile.o -c $(OBJDIR)/winfile_.c

$(OBJDIR)/winfile.h:	$(OBJDIR)/headers

$(OBJDIR)/winhttp_.c:	$(SRCDIR)/winhttp.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/winhttp.c >$@

$(OBJDIR)/winhttp.o:	$(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.h:	$(OBJDIR)/headers

$(OBJDIR)/wysiwyg_.c:	$(SRCDIR)/wysiwyg.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/wysiwyg.c >$@

$(OBJDIR)/wysiwyg.o:	$(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c

$(OBJDIR)/wysiwyg.h:	$(OBJDIR)/headers

$(OBJDIR)/xfer_.c:	$(SRCDIR)/xfer.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfer.c >$@

$(OBJDIR)/xfer.o:	$(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.h:	$(OBJDIR)/headers

$(OBJDIR)/xfersetup_.c:	$(SRCDIR)/xfersetup.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/xfersetup.c >$@

$(OBJDIR)/xfersetup.o:	$(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c

$(OBJDIR)/xfersetup.h:	$(OBJDIR)/headers

$(OBJDIR)/zip_.c:	$(SRCDIR)/zip.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/zip.c >$@

$(OBJDIR)/zip.o:	$(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers

SQLITE_OPTIONS = -DNDEBUG=1 \
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
                -Dfopen=fossil_fopen

MINIZ_OPTIONS = -DMINIZ_NO_STDIO \
                -DMINIZ_NO_TIME \
                -DMINIZ_NO_ARCHIVE_APIS

$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw.mistachkin
	$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/cson_amalgamation.o:	$(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o

$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(SRCDIR)/../win/Makefile.mingw.mistachkin
	$(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o

$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o

$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $(OBJDIR)/miniz.o








|


|




|


|


|


|


|

1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
                -Dfopen=fossil_fopen

MINIZ_OPTIONS = -DMINIZ_NO_STDIO \
                -DMINIZ_NO_TIME \
                -DMINIZ_NO_ARCHIVE_APIS

$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw.mistachkin
	$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $@

$(OBJDIR)/cson_amalgamation.o:	$(SRCDIR)/cson_amalgamation.c
	$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $@

$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(SRCDIR)/../win/Makefile.mingw.mistachkin
	$(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $@

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $@

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $@

$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -c $(SRCDIR)/th_tcl.c -o $@

$(OBJDIR)/miniz.o:	$(SRCDIR)/miniz.c
	$(XTCC) $(MINIZ_OPTIONS) -c $(SRCDIR)/miniz.c -o $@

Changes to win/Makefile.msc.
1
2
3
4








5
6
7
8
9
10
11
#
##############################################################################
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
##############################################################################








#
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
B       = ..
SRCDIR  = $B\src




>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
##############################################################################
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
##############################################################################
#
# This Makefile will only function correctly if used from a sub-directory
# that is a direct child of the top-level directory for this project.
#
!if !exist("..\.fossil-settings")
!error "Please change the current directory to the one containing this file."
!endif

#
# This file is automatically generated.  Instead of editing this
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
# to regenerate this file.
#
B       = ..
SRCDIR  = $B\src
19
20
21
22
23
24
25



26
27
28
29
30
31
32
33
34



35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
















50
51
52
53
54
55
56
# be built from source code.  The PERLDIR variable should point to
# the directory containing the main Perl binary (i.e. "perl.exe").
PERLDIR = C:\Perl\bin
PERL    = perl.exe

# Uncomment to enable debug symbols
# DEBUG = 1




# Uncomment to enable JSON API
# FOSSIL_ENABLE_JSON = 1

# Uncomment to enable miniz usage
# FOSSIL_ENABLE_MINIZ = 1

# Uncomment to enable SSL support
# FOSSIL_ENABLE_SSL = 1




# Uncomment to enable TH1 scripts in embedded documentation files
# FOSSIL_ENABLE_TH1_DOCS = 1

# Uncomment to enable TH1 hooks
# FOSSIL_ENABLE_TH1_HOOKS = 1

# Uncomment to enable Tcl support
# FOSSIL_ENABLE_TCL = 1

!ifdef FOSSIL_ENABLE_SSL
SSLDIR    = $(B)\compat\openssl-1.0.1i
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32

SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
















!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
!endif







>
>
>









>
>
>











|


>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# be built from source code.  The PERLDIR variable should point to
# the directory containing the main Perl binary (i.e. "perl.exe").
PERLDIR = C:\Perl\bin
PERL    = perl.exe

# Uncomment to enable debug symbols
# DEBUG = 1

# Uncomment to support Windows XP with Visual Studio 201x
# FOSSIL_ENABLE_WINXP = 1

# Uncomment to enable JSON API
# FOSSIL_ENABLE_JSON = 1

# Uncomment to enable miniz usage
# FOSSIL_ENABLE_MINIZ = 1

# Uncomment to enable SSL support
# FOSSIL_ENABLE_SSL = 1

# Uncomment to build SSL libraries
# FOSSIL_BUILD_SSL = 1

# Uncomment to enable TH1 scripts in embedded documentation files
# FOSSIL_ENABLE_TH1_DOCS = 1

# Uncomment to enable TH1 hooks
# FOSSIL_ENABLE_TH1_HOOKS = 1

# Uncomment to enable Tcl support
# FOSSIL_ENABLE_TCL = 1

!ifdef FOSSIL_ENABLE_SSL
SSLDIR    = $(B)\compat\openssl-1.0.1j
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32
SSLLFLAGS = /nologo /opt:ref /debug
SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
!message Using 'x64' platform for OpenSSL...
SSLCONFIG = VC-WIN64A no-asm
SSLSETUP  = ms\do_win64a.bat
SSLNMAKE  = ms\nt.mak all
!elseif "$(PLATFORM)"=="ia64"
!message Using 'ia64' platform for OpenSSL...
SSLCONFIG = VC-WIN64I no-asm
SSLSETUP  = ms\do_win64i.bat
SSLNMAKE  = ms\nt.mak all
!else
!message Assuming 'x86' platform for OpenSSL...
SSLCONFIG = VC-WIN32 no-asm
SSLSETUP  = ms\do_ms.bat
SSLNMAKE  = ms\nt.mak all
!endif
!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
!endif
72
73
74
75
76
77
78











79
80
81
82
83
84
85

!ifdef FOSSIL_ENABLE_TCL
INCL      = $(INCL) /I$(TCLINCDIR)
!endif

CFLAGS    = /nologo
LDFLAGS   = /NODEFAULTLIB:msvcrt /MANIFEST:NO












!ifdef DEBUG
CFLAGS    = $(CFLAGS) /Zi /MTd /Od
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) /MT /O2
!endif







>
>
>
>
>
>
>
>
>
>
>







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

!ifdef FOSSIL_ENABLE_TCL
INCL      = $(INCL) /I$(TCLINCDIR)
!endif

CFLAGS    = /nologo
LDFLAGS   = /NODEFAULTLIB:msvcrt /MANIFEST:NO

!ifdef FOSSIL_ENABLE_WINXP
XPCFLAGS  = $(XPCFLAGS) /D_USING_V110_SDK71_=1
CFLAGS    = $(CFLAGS) $(XPCFLAGS)
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
!else
XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
!endif
LDFLAGS   = $(LDFLAGS) $(XPLDFLAGS)
!endif

!ifdef DEBUG
CFLAGS    = $(CFLAGS) /Zi /MTd /Od
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) /MT /O2
!endif
159
160
161
162
163
164
165

166
167
168
169
170
171
172
        allrepo_.c \
        attach_.c \
        bag_.c \
        bisect_.c \
        blob_.c \
        branch_.c \
        browse_.c \

        cache_.c \
        captcha_.c \
        cgi_.c \
        checkin_.c \
        checkout_.c \
        clearsign_.c \
        clone_.c \







>







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
        allrepo_.c \
        attach_.c \
        bag_.c \
        bisect_.c \
        blob_.c \
        branch_.c \
        browse_.c \
        builtin_.c \
        cache_.c \
        captcha_.c \
        cgi_.c \
        checkin_.c \
        checkout_.c \
        clearsign_.c \
        clone_.c \
263
264
265
266
267
268
269


270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
        winfile_.c \
        winhttp_.c \
        wysiwyg_.c \
        xfer_.c \
        xfersetup_.c \
        zip_.c



OBJ   = $(OX)\add$O \
        $(OX)\allrepo$O \
        $(OX)\attach$O \
        $(OX)\bag$O \
        $(OX)\bisect$O \
        $(OX)\blob$O \
        $(OX)\branch$O \
        $(OX)\browse$O \

        $(OX)\cache$O \
        $(OX)\captcha$O \
        $(OX)\cgi$O \
        $(OX)\checkin$O \
        $(OX)\checkout$O \
        $(OX)\clearsign$O \
        $(OX)\clone$O \







>
>








>







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
        winfile_.c \
        winhttp_.c \
        wysiwyg_.c \
        xfer_.c \
        xfersetup_.c \
        zip_.c

EXTRA_FILES   = $(SRCDIR)\diff.tcl

OBJ   = $(OX)\add$O \
        $(OX)\allrepo$O \
        $(OX)\attach$O \
        $(OX)\bag$O \
        $(OX)\bisect$O \
        $(OX)\blob$O \
        $(OX)\branch$O \
        $(OX)\browse$O \
        $(OX)\builtin$O \
        $(OX)\cache$O \
        $(OX)\captcha$O \
        $(OX)\cgi$O \
        $(OX)\checkin$O \
        $(OX)\checkout$O \
        $(OX)\clearsign$O \
        $(OX)\clone$O \
394
395
396
397
398
399
400



401

402
403
404
405
406
407
408
409
410



411

412
413
414
415
416
417
418

419
420

421
422
423

424
425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
PDBNAME    = $(OX)\fossil$(P)
APPTARGETS =

all: $(OX) $(APPNAME)

zlib:
	@echo Building zlib from "$(ZLIBDIR)"...



	@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd


!ifdef FOSSIL_ENABLE_SSL
openssl:
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure VC-WIN32 no-asm && popd
	@pushd "$(SSLDIR)" && call ms\do_ms.bat && popd



	@pushd "$(SSLDIR)" && $(MAKE) /f ms\nt.mak all && popd

!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif

!ifdef FOSSIL_ENABLE_SSL

APPTARGETS = $(APPTARGETS) openssl
!endif


$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
	cd $(OX)

	link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts

$(OX)\linkopts: $B\win\Makefile.msc
	echo $(OX)\add.obj > $@
	echo $(OX)\allrepo.obj >> $@
	echo $(OX)\attach.obj >> $@
	echo $(OX)\bag.obj >> $@
	echo $(OX)\bisect.obj >> $@
	echo $(OX)\blob.obj >> $@
	echo $(OX)\branch.obj >> $@
	echo $(OX)\browse.obj >> $@

	echo $(OX)\cache.obj >> $@
	echo $(OX)\captcha.obj >> $@
	echo $(OX)\cgi.obj >> $@
	echo $(OX)\checkin.obj >> $@
	echo $(OX)\checkout.obj >> $@
	echo $(OX)\clearsign.obj >> $@
	echo $(OX)\clone.obj >> $@







>
>
>

>







|
|
>
>
>
|
>







>


>

|

>











>







440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
PDBNAME    = $(OX)\fossil$(P)
APPTARGETS =

all: $(OX) $(APPNAME)

zlib:
	@echo Building zlib from "$(ZLIBDIR)"...
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
!else
	@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
!endif

!ifdef FOSSIL_ENABLE_SSL
openssl:
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
	@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
!else
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
!endif
!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif

!ifdef FOSSIL_ENABLE_SSL
!ifdef FOSSIL_BUILD_SSL
APPTARGETS = $(APPTARGETS) openssl
!endif
!endif

$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
	cd $(OX)
	codecheck1$E $(SRC)
	link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts

$(OX)\linkopts: $B\win\Makefile.msc
	echo $(OX)\add.obj > $@
	echo $(OX)\allrepo.obj >> $@
	echo $(OX)\attach.obj >> $@
	echo $(OX)\bag.obj >> $@
	echo $(OX)\bisect.obj >> $@
	echo $(OX)\blob.obj >> $@
	echo $(OX)\branch.obj >> $@
	echo $(OX)\browse.obj >> $@
	echo $(OX)\builtin.obj >> $@
	echo $(OX)\cache.obj >> $@
	echo $(OX)\captcha.obj >> $@
	echo $(OX)\cgi.obj >> $@
	echo $(OX)\checkin.obj >> $@
	echo $(OX)\checkout.obj >> $@
	echo $(OX)\clearsign.obj >> $@
	echo $(OX)\clone.obj >> $@
554
555
556
557
558
559
560



561



562
563
564
565
566
567
568

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) $**




mkversion$E: $B\src\mkversion.c



	$(BCC) $**

$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
	$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c

$(OX)\sqlite3$O : $(SRCDIR)\sqlite3.c $B\win\Makefile.msc
	$(TCC) /Fo$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SRCDIR)\sqlite3.c







>
>
>
|
>
>
>







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

makeheaders$E: $(SRCDIR)\makeheaders.c
	$(BCC) $**

mkindex$E: $(SRCDIR)\mkindex.c
	$(BCC) $**

mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
	$(BCC) $**

mkversion$E: $(SRCDIR)\mkversion.c
	$(BCC) $**

codecheck1$E: $(SRCDIR)\codecheck1.c
	$(BCC) $**

$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
	$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c

$(OX)\sqlite3$O : $(SRCDIR)\sqlite3.c $B\win\Makefile.msc
	$(TCC) /Fo$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SRCDIR)\sqlite3.c
583
584
585
586
587
588
589



590
591
592
593
594
595
596
	$** > $@
$(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c
	$(TCC) /Fo$@ /c $**

page_index.h: mkindex$E $(SRC)
	$** > $@




clean:
	-del $(OX)\*.obj
	-del *.obj
	-del *_.c
	-del *.h
	-del *.ilk
	-del *.map







>
>
>







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
	$** > $@
$(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c
	$(TCC) /Fo$@ /c $**

page_index.h: mkindex$E $(SRC)
	$** > $@

builtin_data.h:	mkbuiltin$E $(EXTRA_FILES)
	$** > $@

clean:
	-del $(OX)\*.obj
	-del *.obj
	-del *_.c
	-del *.h
	-del *.ilk
	-del *.map
606
607
608
609
610
611
612




613
614
615
616
617
618
619
	-del translate$P
	-del mkindex$E
	-del mkindex$P
	-del makeheaders$E
	-del makeheaders$P
	-del mkversion$E
	-del mkversion$P





$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h







>
>
>
>







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
	-del translate$P
	-del mkindex$E
	-del mkindex$P
	-del makeheaders$E
	-del makeheaders$P
	-del mkversion$E
	-del mkversion$P
	-del codecheck1$E
	-del codecheck1$P
	-del mkbuiltin$E
	-del mkbuiltin$P

$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h
$(OBJDIR)\json_dir$O : $(SRCDIR)\json_detail.h
670
671
672
673
674
675
676






677
678
679
680
681
682
683
	translate$E $** > $@

$(OX)\browse$O : browse_.c browse.h
	$(TCC) /Fo$@ -c browse_.c

browse_.c : $(SRCDIR)\browse.c
	translate$E $** > $@







$(OX)\cache$O : cache_.c cache.h
	$(TCC) /Fo$@ -c cache_.c

cache_.c : $(SRCDIR)\cache.c
	translate$E $** > $@








>
>
>
>
>
>







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
	translate$E $** > $@

$(OX)\browse$O : browse_.c browse.h
	$(TCC) /Fo$@ -c browse_.c

browse_.c : $(SRCDIR)\browse.c
	translate$E $** > $@

$(OX)\builtin$O : builtin_.c builtin.h
	$(TCC) /Fo$@ -c builtin_.c

builtin_.c : $(SRCDIR)\builtin.c
	translate$E $** > $@

$(OX)\cache$O : cache_.c cache.h
	$(TCC) /Fo$@ -c cache_.c

cache_.c : $(SRCDIR)\cache.c
	translate$E $** > $@

1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314

zip_.c : $(SRCDIR)\zip.c
	translate$E $** > $@

fossil.res : $B\win\fossil.rc
	$(RCC)  /fo $@ $**

headers: makeheaders$E page_index.h VERSION.h
	makeheaders$E add_.c:add.h \
			allrepo_.c:allrepo.h \
			attach_.c:attach.h \
			bag_.c:bag.h \
			bisect_.c:bisect.h \
			blob_.c:blob.h \
			branch_.c:branch.h \
			browse_.c:browse.h \

			cache_.c:cache.h \
			captcha_.c:captcha.h \
			cgi_.c:cgi.h \
			checkin_.c:checkin.h \
			checkout_.c:checkout.h \
			clearsign_.c:clearsign.h \
			clone_.c:clone.h \







|








>







1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392

zip_.c : $(SRCDIR)\zip.c
	translate$E $** > $@

fossil.res : $B\win\fossil.rc
	$(RCC)  /fo $@ $**

headers: makeheaders$E page_index.h builtin_data.h VERSION.h
	makeheaders$E add_.c:add.h \
			allrepo_.c:allrepo.h \
			attach_.c:attach.h \
			bag_.c:bag.h \
			bisect_.c:bisect.h \
			blob_.c:blob.h \
			branch_.c:branch.h \
			browse_.c:browse.h \
			builtin_.c:builtin.h \
			cache_.c:cache.h \
			captcha_.c:captcha.h \
			cgi_.c:cgi.h \
			checkin_.c:checkin.h \
			checkout_.c:checkout.h \
			clearsign_.c:clearsign.h \
			clone_.c:clone.h \
Changes to win/buildmsvc.bat.
190
191
192
193
194
195
196















197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

























218
219
220
221
222
223
224
%__ECHO2% PUSHD "%ROOT%\msvcbld"

IF ERRORLEVEL 1 (
  ECHO Could not change to directory "%ROOT%\msvcbld".
  GOTO errors
)
















REM
REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
REM       anything extra from our command line along (e.g. extra options).
REM
%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %*

IF ERRORLEVEL 1 (
  GOTO errors
)

REM
REM NOTE: Attempt to restore the previously saved directory.
REM
%__ECHO2% POPD

IF ERRORLEVEL 1 (
  ECHO Could not restore directory.
  GOTO errors
)

GOTO no_errors


























:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
%__ECHO2% PUSHD "%ROOT%\msvcbld"

IF ERRORLEVEL 1 (
  ECHO Could not change to directory "%ROOT%\msvcbld".
  GOTO errors
)

REM
REM NOTE: If requested, setup the build environment to refer to the Windows
REM       SDK v7.1A, which is required if the binaries are being built with
REM       Visual Studio 201x and need to work on Windows XP.
REM
IF DEFINED USE_V110SDK71A (
  %_AECHO% Forcing use of the Windows SDK v7.1A...
  CALL :fn_UseV110Sdk71A
)

%_VECHO% Path = '%PATH%'
%_VECHO% Include = '%INCLUDE%'
%_VECHO% Lib = '%LIB%'
%_VECHO% NmakeArgs = '%NMAKE_ARGS%'

REM
REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
REM       anything extra from our command line along (e.g. extra options).
REM
%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %NMAKE_ARGS% %*

IF ERRORLEVEL 1 (
  GOTO errors
)

REM
REM NOTE: Attempt to restore the previously saved directory.
REM
%__ECHO2% POPD

IF ERRORLEVEL 1 (
  ECHO Could not restore directory.
  GOTO errors
)

GOTO no_errors

:fn_UseV110Sdk71A
  IF "%PROCESSOR_ARCHITECTURE%" == "x86" GOTO set_v110Sdk71A_x86
  SET PFILES_SDK71A=%ProgramFiles(x86)%
  GOTO set_v110Sdk71A_done
  :set_v110Sdk71A_x86
  SET PFILES_SDK71A=%ProgramFiles%
  :set_v110Sdk71A_done
  SET PATH=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Bin;%PATH%
  SET INCLUDE=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE%
  IF "%PLATFORM%" == "x64" (
    SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib\x64;%LIB%
  ) ELSE (
    SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib;%LIB%
  )
  CALL :fn_UnsetVariable PFILES_SDK71A
  SET NMAKE_ARGS=%NMAKE_ARGS% FOSSIL_ENABLE_WINXP=1
  GOTO :EOF

:fn_UnsetVariable
  IF NOT "%1" == "" (
    SET %1=
    CALL :fn_ResetErrorLevel
  )
  GOTO :EOF

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
Changes to win/fossil.exe.manifest.
11
12
13
14
15
16
17


18
19
20
21
22
23
24
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>


      <!-- Windows 8.1 -->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      <!-- Windows 8 -->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
      <!-- Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      <!-- Windows Vista -->







>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
      <!-- Windows 8.1 -->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      <!-- Windows 8 -->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
      <!-- Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      <!-- Windows Vista -->
Changes to www/build.wiki.
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
file "<b>win\buildmsvc.bat</b>" may be used and it will attempt to
detect and use the latest installed version of MSVC.<br><br>To enable
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
first <a href="https://www.openssl.org/source/">download the official
source code for OpenSSL</a> and extract it to an appropriately named
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
[/tree?ci=trunk&name=compat | compat] directory (e.g.
"<b>compat/openssl-1.0.1i</b>"), then make sure that some recent
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
and finally run one of the following commands:
<blockquote><pre>
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
</pre></blockquote>
<blockquote><pre>
buildmsvc.bat FOSSIL_ENABLE_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
</pre></blockquote>

<li><p><i>Cygwin</i> → The same as other unix-like systems. It is
recommended to configure using: "<b>configure --disable-internal-sqlite</b>",
making sure you have the "libsqlite3-devel" , "zlib-devel" and
"openssl-devel" packages installed first.
</ol>







|



|


|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
file "<b>win\buildmsvc.bat</b>" may be used and it will attempt to
detect and use the latest installed version of MSVC.<br><br>To enable
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
first <a href="https://www.openssl.org/source/">download the official
source code for OpenSSL</a> and extract it to an appropriately named
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
[/tree?ci=trunk&name=compat | compat] directory (e.g.
"<b>compat/openssl-1.0.1j</b>"), then make sure that some recent
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
and finally run one of the following commands:
<blockquote><pre>
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
</pre></blockquote>
<blockquote><pre>
buildmsvc.bat FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
</pre></blockquote>

<li><p><i>Cygwin</i> → The same as other unix-like systems. It is
recommended to configure using: "<b>configure --disable-internal-sqlite</b>",
making sure you have the "libsqlite3-devel" , "zlib-devel" and
"openssl-devel" packages installed first.
</ol>
Changes to www/makefile.wiki.
55
56
57
58
59
60
61







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
These two files are imports like the SQLite source files, 
and so are not preprocessed.

The VERSION.h header file is generated from other information sources
using a small program called:

  9.  mkversion.c








The src/ subdirectory also contains documentation about the
makeheaders preprocessor program:

  10.  [../src/makeheaders.html | makeheaders.html]

Click on the link to read this documentation.  In addition there is
a [http://www.tcl.tk/ | Tcl] script used to build the various makefiles:

  11.  makemake.tcl

Running this Tcl script will automatically regenerate all makefiles.
In order to add a new source file to the Fossil implementation, simply
edit makemake.tcl to add the new filename, then rerun the script, and
all of the makefiles for all targets will be rebuild.

Finally, there is one of the makefiles generated by makemake.tcl:

  12.  main.mk

The main.mk makefile is invoked from the Makefile in the top-level
directory.  The main.mk is generated by makemake.tcl and should not
be hand edited.  Other makefiles generated by makemake.tcl are in 
other subdirectories (currently all in the win/ subdirectory).

All the other files in the src/ subdirectory (79 files at the time of







>
>
>
>
>
>
>




|




|








|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
These two files are imports like the SQLite source files, 
and so are not preprocessed.

The VERSION.h header file is generated from other information sources
using a small program called:

  9.  mkversion.c

The builtin_data.h header file contains the definitions of C-language
byte-array constants that contain various resources such as scripts and
images.  The builtin_data.h header file is generate from the original
resource files using a small program called:

  10   mkbuiltin.c

The src/ subdirectory also contains documentation about the
makeheaders preprocessor program:

  11.  [../src/makeheaders.html | makeheaders.html]

Click on the link to read this documentation.  In addition there is
a [http://www.tcl.tk/ | Tcl] script used to build the various makefiles:

  12.  makemake.tcl

Running this Tcl script will automatically regenerate all makefiles.
In order to add a new source file to the Fossil implementation, simply
edit makemake.tcl to add the new filename, then rerun the script, and
all of the makefiles for all targets will be rebuild.

Finally, there is one of the makefiles generated by makemake.tcl:

  13.  main.mk

The main.mk makefile is invoked from the Makefile in the top-level
directory.  The main.mk is generated by makemake.tcl and should not
be hand edited.  Other makefiles generated by makemake.tcl are in 
other subdirectories (currently all in the win/ subdirectory).

All the other files in the src/ subdirectory (79 files at the time of
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120














121
122
123
124
125
126
127
updated by Fossil itself.  See the [/help/setting | fossil set manifest]
command for additional information.)

The VERSION.h header file is generated by
a C program: src/mkversion.c.  
To run the VERSION.h generator, first compile the src/mkversion.c
 source file into a command-line program (named "mkversion.exe")
than run:

<blockquote><pre>
mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
</pre></blockquote>

The pathnames in the above command might need to be adjusted to get the
directories right.  The point is that the manifest.uuid, manifest, and
VERSION files
in the root of the source tree are the three arguments and
the generated VERSION.h file appears on standard output.















<a name="preprocessing"></a>
<h1>4.0 Preprocessing</h1>

There are three preprocessors for the Fossil sources.  The mkindex
and translate preprocessors can be run in any order.  The makeheaders
preprocessor must be run after translate.







|










>
>
>
>
>
>
>
>
>
>
>
>
>
>







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
updated by Fossil itself.  See the [/help/setting | fossil set manifest]
command for additional information.)

The VERSION.h header file is generated by
a C program: src/mkversion.c.  
To run the VERSION.h generator, first compile the src/mkversion.c
 source file into a command-line program (named "mkversion.exe")
then run:

<blockquote><pre>
mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
</pre></blockquote>

The pathnames in the above command might need to be adjusted to get the
directories right.  The point is that the manifest.uuid, manifest, and
VERSION files
in the root of the source tree are the three arguments and
the generated VERSION.h file appears on standard output.

The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
The builtin_data.h file contains C-langauge byte-array definitions for
the content of resource files used by Fossil.  To generate the 
builtin_data.h file, first compile the mkbuiltin.c program, then run:

<blockquote><pre>
mkbuiltin.exe diff.tcl <i>OtherFiles...</i> &gt;builtin_data.h
</pre></blockquote>

At the time of this writing, the "diff.tcl" script (a Tcl/Tk script used
to generate implement --tk option on the diff command) is the only resource
file processed using mkbuiltin.exe.  However, new resources will likely be
added using this facility in future versions of Fossil.

<a name="preprocessing"></a>
<h1>4.0 Preprocessing</h1>

There are three preprocessors for the Fossil sources.  The mkindex
and translate preprocessors can be run in any order.  The makeheaders
preprocessor must be run after translate.