Fossil

Check-in [a7d576dd]
Login

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

Overview
Comment:Merge trunk
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | andygoth-circa
Files: files | file ages | folders
SHA1: a7d576ddb2198bdf5976a17dee31d77d518140a5
User & Date: andygoth 2016-10-12 18:35:28
Context
2016-10-12
22:04
Closing because functionality already available in Fossil by clicking on the date in the info page Closed-Leaf check-in: 4f92a663 user: andygoth tags: andygoth-circa
18:35
Merge trunk check-in: a7d576dd user: andygoth tags: andygoth-circa
16:05
Update the built-in SQLite to the next 3.15.0 beta for testing. check-in: 6ef15008 user: drh tags: trunk
2016-09-30
20:43
Merge trunk check-in: de845a67 user: andygoth tags: andygoth-circa
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/add.c.

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
     ** entries should be removed.  2012-02-04 */
     ".fos",
     ".fos-journal",
     ".fos-wal",
     ".fos-shm",
  };

  /* Names of auxiliary files generated by SQLite when the "manifest"
  ** property is enabled
  */
  static const char *const azManifest[] = {



     "manifest",
     "manifest.uuid",

  };


  /*
  ** Names of repository files, if they exist in the checkout.
  */
  static const char *azRepo[4] = { 0, 0, 0, 0 };

  /* Cached setting "manifest" */
  static int cachedManifest = -1;


  if( cachedManifest == -1 ){

    Blob repo;
    cachedManifest = db_get_boolean("manifest",0);






    blob_zero(&repo);
    if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
      const char *zRepo = blob_str(&repo);
      azRepo[0] = zRepo;
      azRepo[1] = mprintf("%s-journal", zRepo);
      azRepo[2] = mprintf("%s-wal", zRepo);
      azRepo[3] = mprintf("%s-shm", zRepo);
................................................................................
    }
  }

  if( N<0 ) return 0;
  if( N<count(azName) ) return azName[N];
  N -= count(azName);
  if( cachedManifest ){
    if( N<count(azManifest) ) return azManifest[N];
    N -= count(azManifest);
  }
  if( !omitRepo && N<count(azRepo) ) return azRepo[N];
  return 0;
}

/*
** Return a list of all reserved filenames as an SQL list.







|
|

|
>
>
>
|
|
>

>








>


>

|
>
>
>
>
>
>







 







|
|







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
     ** entries should be removed.  2012-02-04 */
     ".fos",
     ".fos-journal",
     ".fos-wal",
     ".fos-shm",
  };

  /* Possible names of auxiliary files generated when the "manifest" property
  ** is used
  */
  static const struct {
    const char *fname;
    int flg;
  }aManifestflags[] = {
    { "manifest",      MFESTFLG_RAW },
    { "manifest.uuid", MFESTFLG_UUID },
    { "manifest.tags", MFESTFLG_TAGS }
  };
  static const char *azManifests[3];

  /*
  ** Names of repository files, if they exist in the checkout.
  */
  static const char *azRepo[4] = { 0, 0, 0, 0 };

  /* Cached setting "manifest" */
  static int cachedManifest = -1;
  static int numManifests;

  if( cachedManifest == -1 ){
    int i;
    Blob repo;
    cachedManifest = db_get_manifest_setting();
    numManifests = 0;
    for(i=0; i<count(aManifestflags); i++){
      if( cachedManifest&aManifestflags[i].flg ) {
        azManifests[numManifests++] = aManifestflags[i].fname;
      }
    }
    blob_zero(&repo);
    if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
      const char *zRepo = blob_str(&repo);
      azRepo[0] = zRepo;
      azRepo[1] = mprintf("%s-journal", zRepo);
      azRepo[2] = mprintf("%s-wal", zRepo);
      azRepo[3] = mprintf("%s-shm", zRepo);
................................................................................
    }
  }

  if( N<0 ) return 0;
  if( N<count(azName) ) return azName[N];
  N -= count(azName);
  if( cachedManifest ){
    if( N<numManifests ) return azManifests[N];
    N -= numManifests;
  }
  if( !omitRepo && N<count(azRepo) ) return azRepo[N];
  return 0;
}

/*
** Return a list of all reserved filenames as an SQL list.

Changes to src/allrepo.c.

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
       "INSERT INTO repolist "
       "SELECT DISTINCT substr(name, 6), name COLLATE nocase"
       "  FROM global_config"
       " WHERE substr(name, 1, 5)=='repo:'"
       " ORDER BY 1"
    );
  }
  db_multi_exec("CREATE TEMP TABLE todel(x TEXT)");
  db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFilename = db_column_text(&q, 0);
#if !USE_SEE
    if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
#endif
    if( file_access(zFilename, F_OK)
     || !file_is_canonical(zFilename)
     || (useCheckouts && file_isdir(zFilename)!=1)
    ){
      db_multi_exec("INSERT INTO todel VALUES(%Q)", db_column_text(&q, 1));
      nToDel++;
      continue;
    }
    if( zCmd[0]=='l' ){
      fossil_print("%s\n", zFilename);
      continue;
    }else if( showFile ){







|










|







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
       "INSERT INTO repolist "
       "SELECT DISTINCT substr(name, 6), name COLLATE nocase"
       "  FROM global_config"
       " WHERE substr(name, 1, 5)=='repo:'"
       " ORDER BY 1"
    );
  }
  db_multi_exec("CREATE TEMP TABLE toDel(x TEXT)");
  db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFilename = db_column_text(&q, 0);
#if !USE_SEE
    if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
#endif
    if( file_access(zFilename, F_OK)
     || !file_is_canonical(zFilename)
     || (useCheckouts && file_isdir(zFilename)!=1)
    ){
      db_multi_exec("INSERT INTO toDel VALUES(%Q)", db_column_text(&q, 1));
      nToDel++;
      continue;
    }
    if( zCmd[0]=='l' ){
      fossil_print("%s\n", zFilename);
      continue;
    }else if( showFile ){

Changes to src/blob.c.

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
** Return the number of bytes written.
*/
int blob_write_to_file(Blob *pBlob, const char *zFilename){
  FILE *out;
  int nWrote;

  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, 0);
    out = fossil_fopen(zFilename, "wb");
    if( out==0 ){







      fossil_fatal_recursive("unable to open file \"%s\" for writing",
                             zFilename);
      return 0;
    }
    blob_is_init(pBlob);
    nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out);
    fclose(out);







|

|
|
<



|








>
>
>
>
>
>
>







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
** Return the number of bytes written.
*/
int blob_write_to_file(Blob *pBlob, const char *zFilename){
  FILE *out;
  int nWrote;

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

    fflush(stdout);
    _setmode(_fileno(stdout), _O_BINARY);
#endif
    nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), stdout);
#if defined(_WIN32)
    fflush(stdout);
    _setmode(_fileno(stdout), _O_TEXT);
#endif
  }else{
    file_mkfolder(zFilename, 1, 0);
    out = fossil_fopen(zFilename, "wb");
    if( out==0 ){
#if _WIN32
      const char *zReserved = file_is_win_reserved(zFilename);
      if( zReserved ){
        fossil_fatal("cannot open \"%s\" because \"%s\" is "
             "a reserved name on Windows", zFilename, zReserved);
      }
#endif
      fossil_fatal_recursive("unable to open file \"%s\" for writing",
                             zFilename);
      return 0;
    }
    blob_is_init(pBlob);
    nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out);
    fclose(out);

Changes to src/checkin.c.

1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
....
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
....
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
....
2344
2345
2346
2347
2348
2349
2350










2351
2352
2353
2354
2355
2356
2357
2358
  }
  sCiInfo.zDateOvrd = find_option("date-override",0,1);
  sCiInfo.zUserOvrd = find_option("user-override",0,1);
  db_must_be_within_tree();
  noSign = db_get_boolean("omitsign", 0)|noSign;
  if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
  useCksum = db_get_boolean("repo-cksum", 1);
  outputManifest = db_get_boolean("manifest", 0);
  verify_all_options();

  /* Escape special characters in tags and put all tags in sorted order */
  if( nTag ){
    int i;
    for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]);
    qsort((void*)sCiInfo.azTag, nTag, sizeof(sCiInfo.azTag[0]), tagCmp);
................................................................................

  /* If the -n|--dry-run option is specified, output the manifest file
  ** and rollback the transaction.
  */
  if( dryRunFlag ){
    blob_write_to_file(&manifest, "");
  }
  if( outputManifest ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
    blob_write_to_file(&manifest, zManifestFile);
    blob_reset(&manifest);
    blob_read_from_file(&manifest, zManifestFile);
    free(zManifestFile);
  }

................................................................................
    }else{
      fossil_print("Not_Closed: %s (not a leaf any more)\n", zIntegrateUuid);
    }
  }
  db_finalize(&q);

  fossil_print("New_Version: %s\n", zUuid);
  if( outputManifest ){
    zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
    blob_zero(&muuid);
    blob_appendf(&muuid, "%s\n", zUuid);
    blob_write_to_file(&muuid, zManifestFile);
    free(zManifestFile);
    blob_reset(&muuid);
  }
................................................................................
  db_multi_exec("PRAGMA repository.application_id=252006673;");
  db_multi_exec("PRAGMA localdb.application_id=252006674;");
  if( dryRunFlag ){
    db_end_transaction(1);
    exit(1);
  }
  db_end_transaction(0);











  if( !g.markPrivate ){
    autosync_loop(SYNC_PUSH|SYNC_PULL, db_get_int("autosync-tries", 1), 0);
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}







|







 







|







 







|







 







>
>
>
>
>
>
>
>
>
>








1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
....
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
....
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
....
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
  }
  sCiInfo.zDateOvrd = find_option("date-override",0,1);
  sCiInfo.zUserOvrd = find_option("user-override",0,1);
  db_must_be_within_tree();
  noSign = db_get_boolean("omitsign", 0)|noSign;
  if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
  useCksum = db_get_boolean("repo-cksum", 1);
  outputManifest = db_get_manifest_setting();
  verify_all_options();

  /* Escape special characters in tags and put all tags in sorted order */
  if( nTag ){
    int i;
    for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]);
    qsort((void*)sCiInfo.azTag, nTag, sizeof(sCiInfo.azTag[0]), tagCmp);
................................................................................

  /* If the -n|--dry-run option is specified, output the manifest file
  ** and rollback the transaction.
  */
  if( dryRunFlag ){
    blob_write_to_file(&manifest, "");
  }
  if( outputManifest & MFESTFLG_RAW ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
    blob_write_to_file(&manifest, zManifestFile);
    blob_reset(&manifest);
    blob_read_from_file(&manifest, zManifestFile);
    free(zManifestFile);
  }

................................................................................
    }else{
      fossil_print("Not_Closed: %s (not a leaf any more)\n", zIntegrateUuid);
    }
  }
  db_finalize(&q);

  fossil_print("New_Version: %s\n", zUuid);
  if( outputManifest & MFESTFLG_UUID ){
    zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
    blob_zero(&muuid);
    blob_appendf(&muuid, "%s\n", zUuid);
    blob_write_to_file(&muuid, zManifestFile);
    free(zManifestFile);
    blob_reset(&muuid);
  }
................................................................................
  db_multi_exec("PRAGMA repository.application_id=252006673;");
  db_multi_exec("PRAGMA localdb.application_id=252006674;");
  if( dryRunFlag ){
    db_end_transaction(1);
    exit(1);
  }
  db_end_transaction(0);

  if( outputManifest & MFESTFLG_TAGS ){
    Blob tagslist;
    zManifestFile = mprintf("%smanifest.tags", g.zLocalRoot);
    blob_zero(&tagslist);
    get_checkin_taglist(nvid, &tagslist);
    blob_write_to_file(&tagslist, zManifestFile);
    blob_reset(&tagslist);
    free(zManifestFile);
  }

  if( !g.markPrivate ){
    autosync_loop(SYNC_PUSH|SYNC_PULL, db_get_int("autosync-tries", 1), 0);
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}

Changes to src/checkout.c.

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
}


/*
** If the "manifest" setting is true, then automatically generate
** files named "manifest" and "manifest.uuid" containing, respectively,
** the text of the manifest and the artifact ID of the manifest.



*/
void manifest_to_disk(int vid){
  char *zManFile;
  Blob manifest;
  Blob hash;



  if( db_get_boolean("manifest",0) ){



    blob_zero(&manifest);
    content_get(vid, &manifest);
    zManFile = mprintf("%smanifest", g.zLocalRoot);
    blob_zero(&hash);
    sha1sum_blob(&manifest, &hash);
    sterilize_manifest(&manifest);
    blob_write_to_file(&manifest, zManFile);

    free(zManFile);
    zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
    blob_append(&hash, "\n", 1);
    blob_write_to_file(&hash, zManFile);
    free(zManFile);
    blob_reset(&hash);
  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
      zManFile = mprintf("%smanifest", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }








    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
      zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }













}



































/*
** COMMAND: checkout*
** COMMAND: co*
**
** Usage: %fossil checkout ?VERSION | --latest? ?OPTIONS?
**    or: %fossil co ?VERSION | --latest? ?OPTIONS?







>
>
>





>
>

<
>
>
>


<



<
>
|
|
<
|

<






>
>
>
>
>
>
>
>






>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
}


/*
** If the "manifest" setting is true, then automatically generate
** files named "manifest" and "manifest.uuid" containing, respectively,
** the text of the manifest and the artifact ID of the manifest.
** If the manifest setting is set, but is not a boolean value, then treat
** each character as a flag to enable writing "manifest", "manifest.uuid" or
** "manifest.tags".
*/
void manifest_to_disk(int vid){
  char *zManFile;
  Blob manifest;
  Blob hash;
  Blob taglist;
  int flg;


  flg = db_get_manifest_setting();

  if( flg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
    blob_zero(&manifest);
    content_get(vid, &manifest);

    blob_zero(&hash);
    sha1sum_blob(&manifest, &hash);
    sterilize_manifest(&manifest);

  }
  if( flg & MFESTFLG_RAW ){
    zManFile = mprintf("%smanifest", g.zLocalRoot);

    blob_write_to_file(&manifest, zManFile);
    free(zManFile);

  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
      zManFile = mprintf("%smanifest", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }
  if( flg & MFESTFLG_UUID ){
    zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
    blob_append(&hash, "\n", 1);
    blob_write_to_file(&hash, zManFile);
    free(zManFile);
    blob_reset(&hash);
  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
      zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }
  if( flg & MFESTFLG_TAGS ){
    blob_zero(&taglist);
    zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
    get_checkin_taglist(vid, &taglist);
    blob_write_to_file(&taglist, zManFile);
    free(zManFile);
    blob_reset(&taglist);
  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.tags'") ){
      zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }
}

/*
** Find the branch name and all symbolic tags for a particular check-in
** identified by "rid".
**
** The branch name is actually only extracted if this procedure is run
** from within a local check-out.  And the branch name is not the branch
** name for "rid" but rather the branch name for the current check-out.
** It is unclear if the rid parameter is always the same as the current
** check-out.
*/
void get_checkin_taglist(int rid, Blob *pOut){
  Stmt stmt;
  char *zCurrent;
  blob_reset(pOut);
  zCurrent = db_text(0, "SELECT value FROM tagxref"
                        " WHERE rid=%d AND tagid=%d", rid, TAG_BRANCH);
  blob_appendf(pOut, "branch %s\n", zCurrent);
  db_prepare(&stmt, "SELECT substr(tagname, 5)"
                    "  FROM tagxref, tag"
                    " WHERE tagxref.rid=%d"
                    "   AND tagxref.tagtype>0"
                    "   AND tag.tagid=tagxref.tagid"
                    "   AND tag.tagname GLOB 'sym-*'", rid);
  while( db_step(&stmt)==SQLITE_ROW ){
    const char *zName;
    zName = db_column_text(&stmt, 0);
    blob_appendf(pOut, "tag %s\n", zName);
  }
  db_reset(&stmt);
  db_finalize(&stmt);
}


/*
** COMMAND: checkout*
** COMMAND: co*
**
** Usage: %fossil checkout ?VERSION | --latest? ?OPTIONS?
**    or: %fossil co ?VERSION | --latest? ?OPTIONS?

Changes to src/db.c.

2268
2269
2270
2271
2272
2273
2274



































2275
2276
2277
2278
2279
2280
2281
....
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
....
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782



2783
2784
2785
2786
2787
2788
2789
}
int db_lget_int(const char *zName, int dflt){
  return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset_int(const char *zName, int value){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
}




































/*
** Record the name of a local repository in the global_config() database.
** The repository filename %s is recorded as an entry with a "name" field
** of the following form:
**
**       repo:%s
................................................................................
  { "hash-digits",      0,              5, 0, 0, "10"                  },
  { "http-port",        0,             16, 0, 0, "8080"                },
  { "https-login",      0,              0, 0, 0, "off"                 },
  { "ignore-glob",      0,             40, 1, 0, ""                    },
  { "keep-glob",        0,             40, 1, 0, ""                    },
  { "localauth",        0,              0, 0, 0, "off"                 },
  { "main-branch",      0,             40, 0, 0, "trunk"               },
  { "manifest",         0,              0, 1, 0, "off"                 },
  { "max-loadavg",      0,             25, 0, 0, "0.0"                 },
  { "max-upload",       0,             25, 0, 0, "250000"              },
  { "mtime-changes",    0,              0, 0, 0, "on"                  },
#if FOSSIL_ENABLE_LEGACY_MV_RM
  { "mv-rm-files",      0,              0, 0, 0, "off"                 },
#endif
  { "pgp-command",      0,             40, 0, 0, "gpg --clearsign -o " },
................................................................................
**    localauth        If enabled, require that HTTP connections from
**                     127.0.0.1 be authenticated by password.  If
**                     false, all HTTP requests from localhost have
**                     unrestricted access to the repository.
**
**    main-branch      The primary branch for the project.  Default: trunk
**
**    manifest         If enabled, automatically create files "manifest" and
**     (versionable)   "manifest.uuid" in every checkout.  The SQLite and
**                     Fossil repositories both require this.  Default: off.



**
**    max-loadavg      Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
**                     are disallowed if the system load average goes above this
**                     value.  "0.0" means no limit.  This only works on unix.
**                     Only local settings of this value make a difference since
**                     when running as a web-server, Fossil does not open the
**                     global configuration database.







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







 







|







 







|
|
|
>
>
>







2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
....
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
....
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
}
int db_lget_int(const char *zName, int dflt){
  return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset_int(const char *zName, int value){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
}

#if INTERFACE
/* Manifest generation flags */
#define MFESTFLG_RAW  0x01
#define MFESTFLG_UUID 0x02
#define MFESTFLG_TAGS 0x04
#endif /* INTERFACE */

/*
** Get the manifest setting.  For backwards compatibility first check if the
** value is a boolean.  If it's not a boolean, treat each character as a flag
** to enable a manifest type.  This system puts certain boundary conditions on
** which letters can be used to represent flags (any permutation of flags must
** not be able to fully form one of the boolean values).
*/
int db_get_manifest_setting(void){
  int flg;
  char *zVal = db_get("manifest", 0);
  if( zVal==0 || is_false(zVal) ){
    return 0;
  }else if( is_truth(zVal) ){
    return MFESTFLG_RAW|MFESTFLG_UUID;
  }
  flg = 0;
  while( *zVal ){
    switch( *zVal ){
      case 'r': flg |= MFESTFLG_RAW;  break;
      case 'u': flg |= MFESTFLG_UUID; break;
      case 't': flg |= MFESTFLG_TAGS; break;
    }
    zVal++;
  }
  return flg;
}


/*
** Record the name of a local repository in the global_config() database.
** The repository filename %s is recorded as an entry with a "name" field
** of the following form:
**
**       repo:%s
................................................................................
  { "hash-digits",      0,              5, 0, 0, "10"                  },
  { "http-port",        0,             16, 0, 0, "8080"                },
  { "https-login",      0,              0, 0, 0, "off"                 },
  { "ignore-glob",      0,             40, 1, 0, ""                    },
  { "keep-glob",        0,             40, 1, 0, ""                    },
  { "localauth",        0,              0, 0, 0, "off"                 },
  { "main-branch",      0,             40, 0, 0, "trunk"               },
  { "manifest",         0,              5, 1, 0, "off"                 },
  { "max-loadavg",      0,             25, 0, 0, "0.0"                 },
  { "max-upload",       0,             25, 0, 0, "250000"              },
  { "mtime-changes",    0,              0, 0, 0, "on"                  },
#if FOSSIL_ENABLE_LEGACY_MV_RM
  { "mv-rm-files",      0,              0, 0, 0, "off"                 },
#endif
  { "pgp-command",      0,             40, 0, 0, "gpg --clearsign -o " },
................................................................................
**    localauth        If enabled, require that HTTP connections from
**                     127.0.0.1 be authenticated by password.  If
**                     false, all HTTP requests from localhost have
**                     unrestricted access to the repository.
**
**    main-branch      The primary branch for the project.  Default: trunk
**
**    manifest         If set to a true boolean value, automatically create
**     (versionable)   files "manifest" and "manifest.uuid" in every checkout.
**                     Optionally use combinations of characters 'r'
**                     for "manifest", 'u' for "manifest.uuid" and 't' for
**                     "manifest.tags".  The SQLite and Fossil repositories
**                     both require manifests.  Default: off.
**
**    max-loadavg      Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
**                     are disallowed if the system load average goes above this
**                     value.  "0.0" means no limit.  This only works on unix.
**                     Only local settings of this value make a difference since
**                     when running as a web-server, Fossil does not open the
**                     global configuration database.

Changes to src/deltacmd.c.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
*/
int blob_delta_create(Blob *pOriginal, Blob *pTarget, Blob *pDelta){
  const char *zOrig, *zTarg;
  int lenOrig, lenTarg;
  int len;
  char *zRes;
  blob_zero(pDelta);
  zOrig = blob_buffer(pOriginal);
  lenOrig = blob_size(pOriginal);
  zTarg = blob_buffer(pTarget);
  lenTarg = blob_size(pTarget);
  blob_resize(pDelta, lenTarg+16);
  zRes = blob_buffer(pDelta);
  len = delta_create(zOrig, lenOrig, zTarg, lenTarg, zRes);
  blob_resize(pDelta, len);
  return 0;
}

/*
** COMMAND: test-delta-create







|

|


|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
*/
int blob_delta_create(Blob *pOriginal, Blob *pTarget, Blob *pDelta){
  const char *zOrig, *zTarg;
  int lenOrig, lenTarg;
  int len;
  char *zRes;
  blob_zero(pDelta);
  zOrig = blob_materialize(pOriginal);
  lenOrig = blob_size(pOriginal);
  zTarg = blob_materialize(pTarget);
  lenTarg = blob_size(pTarget);
  blob_resize(pDelta, lenTarg+16);
  zRes = blob_materialize(pDelta);
  len = delta_create(zOrig, lenOrig, zTarg, lenTarg, zRes);
  blob_resize(pDelta, len);
  return 0;
}

/*
** COMMAND: test-delta-create

Changes to src/diff.c.

144
145
146
147
148
149
150
151




152
153
154
155
156
157
158
  DLine *a;
  const char *zNL, *z2;

  /* Count the number of lines in the input file.  Include the last line
  ** in the count even if it lacks the \n terminator
  */
  for(nLine=0, z2=z; (zNL = strchr(z2,'\n'))!=0; z2=zNL+1, nLine++){}
  if( z2[0]!=0 ) nLine++;





  a = fossil_malloc( sizeof(a[0])*nLine );
  memset(a, 0, sizeof(a[0])*nLine);
  if( nLine==0 ){
    *pnLine = 0;
    return a;
  }







|
>
>
>
>







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  DLine *a;
  const char *zNL, *z2;

  /* Count the number of lines in the input file.  Include the last line
  ** in the count even if it lacks the \n terminator
  */
  for(nLine=0, z2=z; (zNL = strchr(z2,'\n'))!=0; z2=zNL+1, nLine++){}
  if( z2[0]!=0 ){
    nLine++;
    do{ z2++; }while( z2[0] );
  }
  if( n!=(int)(z2-z) ) return 0;

  a = fossil_malloc( sizeof(a[0])*nLine );
  memset(a, 0, sizeof(a[0])*nLine);
  if( nLine==0 ){
    *pnLine = 0;
    return a;
  }

Changes to src/diffcmd.c.

772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
...
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
** source check-in is the base check-in for the current check-out.
**
** If the "--to VERSION" option appears, it specifies the check-in from
** which the second version of the file or files is taken.  If there is
** no "--to" option then the (possibly edited) files in the current check-out
** are used.
**
** If the "--checkin VERSION" option shows the changes made by
** check-in VERSION relative to its primary parent
**
** The "-i" command-line option forces the use of the internal diff logic
** rather than any external diff program that might be configured using
** the "setting" command.  If no external diff program is configured, then
** the "-i" option is a no-op.  The "-i" option converts "gdiff" into "diff".
**
** The "-N" or "--new-file" option causes the complete text of added or
................................................................................
                      diffFlags, pFileDir);
  }
  if( pFileDir ){
    int i;
    for(i=0; pFileDir[i].zName; i++){
      if( pFileDir[i].nUsed==0
       && strcmp(pFileDir[0].zName,".")!=0
       && !file_isdir(g.argv[i+2])
      ){
        fossil_fatal("not found: '%s'", g.argv[i+2]);
      }
      fossil_free(pFileDir[i].zName);
    }
    fossil_free(pFileDir);
  }







|
|







 







|







772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
...
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
** source check-in is the base check-in for the current check-out.
**
** If the "--to VERSION" option appears, it specifies the check-in from
** which the second version of the file or files is taken.  If there is
** no "--to" option then the (possibly edited) files in the current check-out
** are used.
**
** The "--checkin VERSION" option shows the changes made by
** check-in VERSION relative to its primary parent.
**
** The "-i" command-line option forces the use of the internal diff logic
** rather than any external diff program that might be configured using
** the "setting" command.  If no external diff program is configured, then
** the "-i" option is a no-op.  The "-i" option converts "gdiff" into "diff".
**
** The "-N" or "--new-file" option causes the complete text of added or
................................................................................
                      diffFlags, pFileDir);
  }
  if( pFileDir ){
    int i;
    for(i=0; pFileDir[i].zName; i++){
      if( pFileDir[i].nUsed==0
       && strcmp(pFileDir[0].zName,".")!=0
       && !file_wd_isdir(g.argv[i+2])
      ){
        fossil_fatal("not found: '%s'", g.argv[i+2]);
      }
      fossil_free(pFileDir[i].zName);
    }
    fossil_free(pFileDir);
  }

Changes to src/file.c.

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
...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
...
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
....
1382
1383
1384
1385
1386
1387
1388







































  }else{
    rc = getStat(0, 0);
  }
  return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
}

/*
** Same as file_isdir(), but takes into account symlinks.



*/
int file_wd_isdir(const char *zFilename){
  int rc;


  if( zFilename ){
    char *zFN = mprintf("%s", zFilename);
    file_simplify_name(zFN, -1, 0);
    rc = getStat(zFN, 1);
    free(zFN);








  }else{
    rc = getStat(0, 1);

  }
  return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);


}


/*
** Wrapper around the access() system call.
*/
int file_access(const char *zFilename, int flags){
................................................................................
int file_wd_setexe(const char *zFilename, int onoff){
  int rc = 0;
#if !defined(_WIN32)
  struct stat buf;
  if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0;
  if( onoff ){
    int targetMode = (buf.st_mode & 0444)>>2;
    if( (buf.st_mode & 0100) == 0 ){
      chmod(zFilename, buf.st_mode | targetMode);
      rc = 1;
    }
  }else{
    if( (buf.st_mode & 0100) != 0 ){
      chmod(zFilename, buf.st_mode & ~0111);
      rc = 1;
    }
  }
#endif /* _WIN32 */
  return rc;
}
................................................................................
      /*
      ** On Windows, local path looks like: C:/develop/project/file.txt
      ** The if stops us from trying to create a directory of a drive letter
      ** C: in this example.
      */
      if( !(i==2 && zName[1]==':') ){
#endif
        if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
          if (errorReturn <= 0) {
            fossil_fatal_recursive("unable to create directory %s", zName);
          }
          rc = errorReturn;
          break;
        }
#if defined(_WIN32) || defined(__CYGWIN__)
................................................................................
  fossil_path_free(uName);
  fossil_unicode_free(uMode);
#else
  FILE *f = fopen(zName, zMode);
#endif
  return f;
}














































|
>
>
>



>

<
|
|
|
|
>
>
>
>
>
>
>
>

<
>

<
>
>







 







|




|







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
....
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
  }else{
    rc = getStat(0, 0);
  }
  return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
}

/*
** Same as file_isdir(), but takes into account symlinks.  Return 1 if
** zFilename is a directory -OR- a symlink that points to a directory.
** Return 0 if zFilename does not exist.  Return 2 if zFilename exists
** but is something other than a directory.
*/
int file_wd_isdir(const char *zFilename){
  int rc;
  char *zFN;


  zFN = mprintf("%s", zFilename);
  file_simplify_name(zFN, -1, 0);
  rc = getStat(zFN, 1);
  if( rc ){
    rc = 0; /* It does not exist at all. */
  }else if( S_ISDIR(fileStat.st_mode) ){
    rc = 1; /* It exists and is a real directory. */
  }else if( S_ISLNK(fileStat.st_mode) ){
    Blob content;
    blob_read_link(&content, zFN); /* It exists and is a link. */
    rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
    blob_reset(&content);
  }else{

    rc = 2; /* It exists and is something else. */
  }

  free(zFN);
  return rc;
}


/*
** Wrapper around the access() system call.
*/
int file_access(const char *zFilename, int flags){
................................................................................
int file_wd_setexe(const char *zFilename, int onoff){
  int rc = 0;
#if !defined(_WIN32)
  struct stat buf;
  if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0;
  if( onoff ){
    int targetMode = (buf.st_mode & 0444)>>2;
    if( (buf.st_mode & 0100)==0 ){
      chmod(zFilename, buf.st_mode | targetMode);
      rc = 1;
    }
  }else{
    if( (buf.st_mode & 0100)!=0 ){
      chmod(zFilename, buf.st_mode & ~0111);
      rc = 1;
    }
  }
#endif /* _WIN32 */
  return rc;
}
................................................................................
      /*
      ** On Windows, local path looks like: C:/develop/project/file.txt
      ** The if stops us from trying to create a directory of a drive letter
      ** C: in this example.
      */
      if( !(i==2 && zName[1]==':') ){
#endif
        if( file_mkdir(zName, forceFlag) && file_wd_isdir(zName)!=1 ){
          if (errorReturn <= 0) {
            fossil_fatal_recursive("unable to create directory %s", zName);
          }
          rc = errorReturn;
          break;
        }
#if defined(_WIN32) || defined(__CYGWIN__)
................................................................................
  fossil_path_free(uName);
  fossil_unicode_free(uMode);
#else
  FILE *f = fopen(zName, zMode);
#endif
  return f;
}

/*
** Return non-NULL if zFilename contains pathname elements that
** are reserved on Windows.  The returned string is the disallowed
** path element.
*/
const char *file_is_win_reserved(const char *zPath){
  static const char *azRes[] = { "CON", "PRN", "AUX", "NUL", "COM", "LPT" };
  static char zReturn[5];
  int i;
  while( zPath[0] ){
    for(i=0; i<ArraySize(azRes); i++){
      if( sqlite3_strnicmp(zPath, azRes[i], 3)==0
       && ((i>=4 && fossil_isdigit(zPath[3])
                 && (zPath[4]=='/' || zPath[4]=='.' || zPath[4]==0))
          || (i<4 && (zPath[3]=='/' || zPath[3]=='.' || zPath[3]==0)))
      ){
        sqlite3_snprintf(5,zReturn,"%.*s", i>=4 ? 4 : 3, zPath);
        return zReturn;
      }
    }
    while( zPath[0] && zPath[0]!='/' ) zPath++;
    while( zPath[0]=='/' ) zPath++;
  }
  return 0;
}

/*
** COMMAND: test-valid-for-windows
** Usage:  fossil test-valid-for-windows FILENAME ....
**
** Show which filenames are not valid for Windows
*/
void file_test_valid_for_windows(void){
  int i;
  for(i=2; i<g.argc; i++){
    fossil_print("%s %s\n", file_is_win_reserved(g.argv[i]), g.argv[i]);
  }
}

Changes to src/main.mk.

496
497
498
499
500
501
502


503
504
505
506
507
508
509
                 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 -DSQLITE_OMIT_DECLTYPE \
                 -DSQLITE_OMIT_DEPRECATED \
                 -DSQLITE_OMIT_PROGRESS_CALLBACK \
                 -DSQLITE_OMIT_SHARED_CACHE \
                 -DSQLITE_OMIT_LOAD_EXTENSION \


                 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 -DSQLITE_ENABLE_FTS4 \
                 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_JSON1 \







>
>







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
                 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 -DSQLITE_OMIT_DECLTYPE \
                 -DSQLITE_OMIT_DEPRECATED \
                 -DSQLITE_OMIT_PROGRESS_CALLBACK \
                 -DSQLITE_OMIT_SHARED_CACHE \
                 -DSQLITE_OMIT_LOAD_EXTENSION \
                 -DSQLITE_MAX_EXPR_DEPTH=0 \
                 -DSQLITE_USE_ALLOCA \
                 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 -DSQLITE_ENABLE_FTS4 \
                 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_JSON1 \

Changes to src/makemake.tcl.

162
163
164
165
166
167
168


169
170
171
172
173
174
175
  -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1
  -DSQLITE_LIKE_DOESNT_MATCH_BLOBS
  -DSQLITE_OMIT_DECLTYPE
  -DSQLITE_OMIT_DEPRECATED
  -DSQLITE_OMIT_PROGRESS_CALLBACK
  -DSQLITE_OMIT_SHARED_CACHE
  -DSQLITE_OMIT_LOAD_EXTENSION


  -DSQLITE_ENABLE_LOCKING_STYLE=0
  -DSQLITE_DEFAULT_FILE_FORMAT=4
  -DSQLITE_ENABLE_EXPLAIN_COMMENTS
  -DSQLITE_ENABLE_FTS4
  -DSQLITE_ENABLE_FTS3_PARENTHESIS
  -DSQLITE_ENABLE_DBSTAT_VTAB
  -DSQLITE_ENABLE_JSON1







>
>







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1
  -DSQLITE_LIKE_DOESNT_MATCH_BLOBS
  -DSQLITE_OMIT_DECLTYPE
  -DSQLITE_OMIT_DEPRECATED
  -DSQLITE_OMIT_PROGRESS_CALLBACK
  -DSQLITE_OMIT_SHARED_CACHE
  -DSQLITE_OMIT_LOAD_EXTENSION
  -DSQLITE_MAX_EXPR_DEPTH=0
  -DSQLITE_USE_ALLOCA
  -DSQLITE_ENABLE_LOCKING_STYLE=0
  -DSQLITE_DEFAULT_FILE_FORMAT=4
  -DSQLITE_ENABLE_EXPLAIN_COMMENTS
  -DSQLITE_ENABLE_FTS4
  -DSQLITE_ENABLE_FTS3_PARENTHESIS
  -DSQLITE_ENABLE_DBSTAT_VTAB
  -DSQLITE_ENABLE_JSON1

Changes to src/sqlite3.c.

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
.....
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571



















15572
15573
15574
15575
15576
15577
15578
.....
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611








15612
15613
15614
15615
15616
15617
15618
.....
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
.....
16988
16989
16990
16991
16992
16993
16994
16995
16996
16997
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011
.....
17070
17071
17072
17073
17074
17075
17076
17077
17078
17079
17080
17081
17082
17083
17084
.....
17158
17159
17160
17161
17162
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
.....
17718
17719
17720
17721
17722
17723
17724
17725
17726
17727
17728
17729
17730
17731
17732
17733
17734
.....
17795
17796
17797
17798
17799
17800
17801






17802
17803
17804
17805
17806
17807
17808
.....
17839
17840
17841
17842
17843
17844
17845
17846
17847
17848
17849
17850
17851
17852
17853
17854
17855
17856
17857
.....
17984
17985
17986
17987
17988
17989
17990
17991
17992
17993
17994
17995
17996
17997
17998
17999
18000
18001
18002
18003
18004
18005
18006
18007
18008
18009
.....
18020
18021
18022
18023
18024
18025
18026




















18027
18028
18029
18030
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044
18045
18046
18047
18048
18049
18050
18051

18052
18053
18054
18055
18056
18057
18058
18059
18060
18061
18062
18063
18064
18065
18066
18067
18068
18069
18070
18071
18072
18073
18074
18075
18076
18077
18078
18079
18080
.....
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094

18095
18096
18097
18098
18099
18100
18101
18102
.....
28774
28775
28776
28777
28778
28779
28780



28781

28782
28783
28784
28785
28786
28787
28788
.....
44017
44018
44019
44020
44021
44022
44023
44024
44025
44026
44027
44028
44029
44030
44031
.....
58983
58984
58985
58986
58987
58988
58989
58990
58991
58992
58993
58994
58995
58996
58997
.....
64320
64321
64322
64323
64324
64325
64326
64327
64328
64329
64330
64331
64332
64333
64334
64335
.....
68021
68022
68023
68024
68025
68026
68027
68028
68029
68030
68031
68032
68033
68034
68035
68036
68037
68038
68039
68040
68041
68042
68043
68044
68045
68046
68047
68048
68049
68050
.....
69040
69041
69042
69043
69044
69045
69046

69047
69048
69049
69050
69051
69052
69053
.....
69339
69340
69341
69342
69343
69344
69345
69346
69347
69348
69349
69350
69351
69352
69353
.....
70016
70017
70018
70019
70020
70021
70022
70023
70024
70025
70026
70027
70028
70029
70030
70031
70032
70033
.....
70143
70144
70145
70146
70147
70148
70149
70150
70151
70152
70153
70154
70155
70156
70157
.....
70486
70487
70488
70489
70490
70491
70492
70493
70494

70495
70496
70497
70498
70499
70500
70501
.....
70649
70650
70651
70652
70653
70654
70655
70656
70657
70658
70659
70660
70661
70662
70663
70664
70665
.....
70839
70840
70841
70842
70843
70844
70845
70846
70847
70848
70849
70850
70851
70852
70853
.....
71230
71231
71232
71233
71234
71235
71236

71237
71238
71239
71240
71241
71242
71243
71244
71245
71246
71247
71248
71249
71250
71251
71252
.....
71361
71362
71363
71364
71365
71366
71367
71368
71369
71370
71371
71372
71373
71374
71375
.....
71923
71924
71925
71926
71927
71928
71929















71930
71931
71932
71933
71934
71935
71936
.....
72135
72136
72137
72138
72139
72140
72141

72142
72143
72144
72145
72146
72147
72148
.....
72277
72278
72279
72280
72281
72282
72283
72284
72285
72286
72287
72288
72289
72290
72291
.....
72366
72367
72368
72369
72370
72371
72372
72373
72374
72375
72376
72377
72378
72379
72380
72381
72382
72383
.....
72398
72399
72400
72401
72402
72403
72404
72405
72406
72407
72408
72409
72410
72411
72412
72413
72414
72415
72416
72417
72418
72419
72420
72421



72422
72423
72424
72425
72426









72427
72428
72429
72430
72431
72432
72433
72434
72435
.....
72573
72574
72575
72576
72577
72578
72579
72580
72581
72582
72583
72584
72585
72586
72587
72588
72589
72590
72591
72592
72593
.....
73341
73342
73343
73344
73345
73346
73347
73348
73349
73350
73351
73352
73353
73354
73355
.....
73405
73406
73407
73408
73409
73410
73411
73412
73413
73414
73415
73416
73417
73418


73419
73420


73421
73422
73423
73424
73425
73426
73427
73428
73429
73430
73431
.....
76663
76664
76665
76666
76667
76668
76669
76670
76671
76672
76673
76674
76675
76676
76677
.....
78415
78416
78417
78418
78419
78420
78421

78422
78423
78424
78425
78426

78427
78428
78429
78430
78431
78432
78433
.....
82336
82337
82338
82339
82340
82341
82342
82343
82344
82345
82346
82347
82348
82349
82350
82351
82352
.....
88781
88782
88783
88784
88785
88786
88787
88788
88789
88790
88791
88792
88793
88794
88795
.....
88810
88811
88812
88813
88814
88815
88816
88817
88818
88819
88820
88821
88822
88823
88824
.....
88870
88871
88872
88873
88874
88875
88876
88877

88878
88879
88880
88881
88882
88883
88884
.....
90410
90411
90412
90413
90414
90415
90416
90417
90418
90419
90420
90421
90422
90423
90424
.....
90628
90629
90630
90631
90632
90633
90634
90635
90636
90637
90638
90639
90640
90641
90642
90643

90644
90645
90646
90647
90648
90649
90650
90651
90652
90653
90654
90655
90656
90657
90658
90659
90660
90661
90662
90663
90664
90665
90666
90667
90668
90669
90670
90671
90672
90673
90674
90675
90676
90677
90678
90679
90680
90681
90682
90683
90684
90685
90686
90687
90688
90689
90690
90691
90692
90693
90694
90695
90696
90697
90698
90699
90700
90701
90702
90703
90704
90705
90706
90707
90708
.....
92654
92655
92656
92657
92658
92659
92660
92661
92662
92663

92664
92665
92666
92667
92668
92669
92670
92671
92672
92673
92674
92675
92676
92677
92678
92679
92680
92681
92682
92683
92684
92685
92686



92687
92688
92689
92690
92691
92692
92693
.....
92709
92710
92711
92712
92713
92714
92715
92716
92717
92718
92719
92720
92721
92722
92723
92724
92725
92726
92727
92728
92729
92730
92731
92732
92733
92734
92735
92736
92737
92738
92739
92740
92741
92742
92743
92744
92745
92746





92747
92748
92749
92750
92751
92752
92753
92754
92755
92756
92757
92758
92759
92760
92761
92762
92763
92764
92765
92766
92767

92768
92769


92770
92771
92772
92773
92774
92775
92776
.....
92786
92787
92788
92789
92790
92791
92792
92793
92794
92795
92796
92797
92798
92799
92800
92801
92802
92803
92804


92805
92806
92807
92808
92809
92810
92811
92812
92813
92814
92815
92816
92817
92818
92819
92820
92821
92822
92823
92824
92825
.....
92889
92890
92891
92892
92893
92894
92895
92896
92897
92898
92899
92900
92901
92902
92903
92904
.....
92922
92923
92924
92925
92926
92927
92928
92929
92930
92931
92932
92933
92934
92935
92936
92937
92938


92939
92940

92941
92942
92943
92944
92945
92946
92947
.....
92965
92966
92967
92968
92969
92970
92971
92972
92973
92974
92975
92976
92977
92978
92979
.....
94661
94662
94663
94664
94665
94666
94667
94668
94669
94670
94671
94672
94673
94674
94675
.....
98431
98432
98433
98434
98435
98436
98437
98438
98439
98440
98441
98442
98443
98444
98445
.....
98458
98459
98460
98461
98462
98463
98464

98465
98466

98467
98468
98469
98470
98471
98472
98473
98474
98475
98476
98477
98478
98479
.....
98516
98517
98518
98519
98520
98521
98522
98523
98524
98525
98526
98527
98528
98529
98530
98531
98532
98533
98534
98535
98536
98537
98538
98539
.....
98545
98546
98547
98548
98549
98550
98551
98552
98553
98554
98555
98556
98557
98558
98559
98560
98561
98562
98563
98564
98565
98566
98567
98568
98569
98570
98571
98572
98573
98574
98575
98576
......
102329
102330
102331
102332
102333
102334
102335
102336
102337
102338
102339
102340
102341
102342
102343
102344
102345
102346
102347
102348
102349
102350
102351
......
109549
109550
109551
109552
109553
109554
109555

109556
109557
109558
109559
109560
109561
109562
......
114045
114046
114047
114048
114049
114050
114051
114052
114053
114054
114055
114056
114057
114058
114059
114060
114061
114062


114063
114064
114065
114066
114067
114068
114069
114070
......
114100
114101
114102
114103
114104
114105
114106
114107
114108
114109
114110
114111
114112
114113
114114
114115
114116
114117
114118
114119
114120
114121
114122
114123
114124
114125
114126
114127
114128
114129
114130
114131
114132
114133
114134
114135
114136
114137
114138
114139
114140
114141
114142
114143
114144
114145
114146
114147
114148
114149
114150
114151
114152
114153
114154
114155
114156
114157
114158
114159
114160
114161
114162
114163
114164
114165
114166
114167
114168
114169
114170
114171
114172
114173
114174
114175
114176
114177
114178
114179
114180
114181
114182
114183
114184
114185
114186
114187
114188
114189
114190
114191
114192
114193
114194
114195
114196
114197
114198
114199
114200
114201
114202
......
115393
115394
115395
115396
115397
115398
115399
115400
115401
115402
115403
115404
115405
115406
115407
......
124053
124054
124055
124056
124057
124058
124059






124060
124061
124062
124063
124064
124065
124066
124067
124068
124069
124070
124071
124072
124073
124074
124075
124076
124077
124078
124079
124080
......
124219
124220
124221
124222
124223
124224
124225
124226
124227
124228
124229




124230

124231
124232
124233
124234
124235
124236
124237
124238

124239
124240
124241
124242
124243
124244
124245
124246
124247
124248
124249
124250
124251
......
124701
124702
124703
124704
124705
124706
124707
124708
124709
124710
124711
124712
124713
124714
124715
......
125787
125788
125789
125790
125791
125792
125793
125794
125795
125796
125797
125798

125799
125800
125801
125802
125803
125804
125805
......
125841
125842
125843
125844
125845
125846
125847
125848
125849
125850
125851
125852
125853
125854
125855
......
125891
125892
125893
125894
125895
125896
125897
125898
125899
125900
125901
125902
125903
125904
125905
......
126327
126328
126329
126330
126331
126332
126333
126334
126335
126336
126337
126338
126339
126340
126341
......
126345
126346
126347
126348
126349
126350
126351
126352
126353
126354
126355
126356
126357
126358
126359
126360
126361
126362
126363
126364
126365
......
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
......
130046
130047
130048
130049
130050
130051
130052
130053
130054
130055
130056
130057
130058
130059
130060
......
131492
131493
131494
131495
131496
131497
131498
131499
131500
131501
131502
131503
131504
131505
131506
......
131946
131947
131948
131949
131950
131951
131952

131953
131954


131955
131956
131957


131958
131959
131960
131961
131962
131963
131964
......
132230
132231
132232
132233
132234
132235
132236
132237
132238
132239
132240
132241
132242
132243
132244
132245
132246
132247
132248


132249
132250
132251
132252



132253
132254
132255
132256
132257
132258
132259
......
135702
135703
135704
135705
135706
135707
135708

135709
135710
135711
135712
135713
135714
135715
135716
135717
......
136476
136477
136478
136479
136480
136481
136482
136483
136484
136485
136486
136487
136488
136489
136490
......
164333
164334
164335
164336
164337
164338
164339
164340
164341


164342
164343

164344
164345
164346
164347
164348
164349
164350
......
181167
181168
181169
181170
181171
181172
181173
181174
181175
181176
181177
181178
181179
181180
181181
......
181533
181534
181535
181536
181537
181538
181539



181540
181541
181542
181543
181544
181545
181546
......
181689
181690
181691
181692
181693
181694
181695
181696
181697
181698
181699
181700
181701
181702
181703
......
195624
195625
195626
195627
195628
195629
195630
195631
195632
195633
195634
195635
195636
195637
195638
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.15.0"
#define SQLITE_VERSION_NUMBER 3015000
#define SQLITE_SOURCE_ID      "2016-09-28 16:05:53 40c0fb0af678797c39a99853f9f4102464c16f4b"

/*
** 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
................................................................................
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  u8 okConstFactor;    /* OK to factor out constants */
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 nColCache;        /* Number of entries in aColCache[] */
  int aTempReg[8];     /* Holding area for temporary registers */
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
  int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
  int iFixedOp;        /* Never back out opcodes iFixedOp-1 or earlier */
  int ckBase;          /* Base register of data during check constraints */
  int iSelfTab;        /* Table of an index whose exprs are being coded */
  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  int nLabel;          /* Number of labels used */
  int *aLabel;         /* Space to hold the labels */
  struct yColCache {
    int iTable;           /* Table cursor number */
    i16 iColumn;          /* Table column number */
    u8 tempReg;           /* iReg is a temp register that needs to be freed */
    int iLevel;           /* Nesting level */
    int iReg;             /* Reg with value of this column. 0 means none. */
    int lru;              /* Least recently used entry has the smallest value */
  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
  ExprList *pConstExpr;/* Constant expressions */
  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. */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  int addrCrTab;       /* Address of OP_CreateTable opcode on CREATE TABLE */
  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* columns referenced */
  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  u8 disableTriggers;  /* True to disable triggers */




















  /************************************************************************
  ** Above is constant between recursions.  Below is reset before and after
  ** each recursion.  The boundary between these two regions is determined
  ** using offsetof(Parse,nVar) so the nVar field must be the first field
  ** in the recursive region.
  ************************************************************************/
................................................................................
  int nzVar;                /* Number of available slots in azVar[] */
  u8 iPkSortOrder;          /* ASC or DESC for INTEGER PRIMARY KEY */
  u8 explain;               /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  u8 declareVtab;           /* True if inside sqlite3_declare_vtab() */
  int nVtabLock;            /* Number of virtual tables to lock */
#endif
  int nAlias;               /* Number of aliased result set columns */
  int nHeight;              /* Expression tree height of current sub-select */
#ifndef SQLITE_OMIT_EXPLAIN
  int iSelectId;            /* ID of current select for EXPLAIN output */
  int iNextSelectId;        /* Next available select ID for EXPLAIN output */
#endif
  char **azVar;             /* Pointers to names of parameters */
  Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
  const char *zTail;        /* All SQL text past the last semicolon parsed */
  Table *pNewTable;         /* A table being constructed by CREATE TABLE */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
  Token sNameToken;         /* Token with unqualified schema object name */
  Token sLastToken;         /* The last token parsed */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  Token sArg;               /* Complete text of a module argument */
  Table **apVtabLock;       /* Pointer to virtual tables needing locking */
#endif
  Table *pZombieTab;        /* List of Table objects to delete after code gen */
  TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
  With *pWith;              /* Current WITH clause, or NULL */
  With *pWithToFree;        /* Free this WITH object at the end of the parse */
};









/*
** Return true if currently inside an sqlite3_declare_vtab() call.
*/
#ifdef SQLITE_OMIT_VIRTUALTABLE
  #define IN_DECLARE_VTAB 0
#else
  #define IN_DECLARE_VTAB (pParse->declareVtab)
................................................................................
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
................................................................................
** Bit 0x20 is set if the mapped character requires translation to upper
** case. i.e. if the character is a lower-case ASCII character.
** If x is a lower-case ASCII character, then its upper-case equivalent
** is (x - 0x20). Therefore toupper() can be implemented as:
**
**   (x & ~(map[x]&0x20))
**
** Standard function tolower() is implemented using the sqlite3UpperToLower[]
** array. tolower() is used more often than toupper() by SQLite.
**
** Bit 0x40 is set if the character non-alphanumeric and can be used in an 
** SQLite identifier.  Identifiers are alphanumerics, "_", "$", and any
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.
**
** SQLite's versions are identical to the standard versions assuming a
** locale of "C". They are implemented as macros in sqliteInt.h.
*/
#ifdef SQLITE_ASCII
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
................................................................................
** page size in bytes.
*/
#ifndef SQLITE_SORTER_PMASZ
# define SQLITE_SORTER_PMASZ 250
#endif

/* Statement journals spill to disk when their size exceeds the following
** threashold (in bytes). 0 means that statement journals are created and
** written to disk immediately (the default behavior for SQLite versions
** before 3.12.0).  -1 means always keep the entire statement journal in
** memory.  (The statement journal is also always held entirely in memory
** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
** setting.)
*/
#ifndef SQLITE_STMTJRNL_SPILL 
................................................................................
};


/*
** The value of the "pending" byte must be 0x40000000 (1 byte past the
** 1-gibabyte boundary) in a compatible database.  SQLite never uses
** the database page that contains the pending byte.  It never attempts
** to read or write that page.  The pending byte page is set assign
** for use by the VFS layers as space for managing file locks.
**
** During testing, it is often desirable to move the pending byte to
** 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.
................................................................................
** Boolean values
*/
typedef unsigned Bool;

/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;

/* Opaque type used by the explainer */
typedef struct Explain Explain;

/* Elements of the linked list at Vdbe.pAuxData */
typedef struct AuxData AuxData;

/* Types of VDBE cursors */
#define CURTYPE_BTREE       0
#define CURTYPE_SORTER      1
#define CURTYPE_VTAB        2
................................................................................
  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[] */
};







/*
** When a sub-program is executed (OP_Program), a structure of this type
** is allocated to store the current value of the program counter, as
** well as the current memory cell array and various other frame specific
** values stored in the Vdbe struct. When the sub-program is finished, 
** these values are copied back to the Vdbe from the VdbeFrame structure,
** restoring the state of the VM to as it was before the sub-program
................................................................................
  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.
*/
#define CACHE_STALE 0

/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
*/
struct Mem {
  union MemValue {
................................................................................
  int isError;            /* Error code returned by the function. */
  u8 skipFlag;            /* Skip accumulator loading if true */
  u8 fErrorOrAux;         /* isError!=0 or pVdbe->pAuxData modified */
  u8 argc;                /* Number of arguments */
  sqlite3_value *argv[1]; /* Argument set */
};

/*
** An Explain object accumulates indented output which is helpful
** in describing recursive data structures.
*/
struct Explain {
  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
  StrAccum str;      /* The string being accumulated */
  int nIndent;       /* Number of elements in aIndent */
  u16 aIndent[100];  /* Levels of indentation */
  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 {
................................................................................
** 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.
*/
struct Vdbe {
  sqlite3 *db;            /* The database connection that owns this statement */




















  Op *aOp;                /* Space to hold the virtual machine's program */
  Mem *aMem;              /* The memory locations */
  Mem **apArg;            /* Arguments to currently executing user function */
  Mem *aColName;          /* Column names to return */
  Mem *pResultSet;        /* Pointer to an array of results */
  Parse *pParse;          /* Parsing context used to create this Vdbe */
  int nMem;               /* Number of memory locations currently allocated */
  int nOp;                /* Number of instructions in the program */
  int nCursor;            /* Number of slots in apCsr[] */
  u32 magic;              /* Magic number for sanity checking */
  char *zErrMsg;          /* Error message written here */
  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
  Mem *aVar;              /* Values for the OP_Variable opcode. */
  char **azVar;           /* Name of variables */
  ynVar nVar;             /* Number of entries in aVar[] */
  ynVar nzVar;            /* Number of entries in azVar[] */
  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
#ifdef SQLITE_DEBUG
  int rcApp;              /* errcode set by sqlite3_result_error_code() */
#endif
  u16 nResColumn;         /* Number of columns in one row of the result set */
  u8 errorAction;         /* Recovery action to do in case of an error */

  bft expired:1;          /* True if the VM needs to be recompiled */
  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  bft explain:2;          /* True if EXPLAIN present on SQL command */
  bft changeCntOn:1;      /* True to update the change-counter */
  bft runOnlyOnce:1;      /* Automatically expire on reset */
  bft usesStmtJournal:1;  /* True if uses a statement journal */
  bft readOnly:1;         /* True for statements that do not write */
  bft bIsReader:1;        /* True for statements that read */
  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
  int nChange;            /* Number of db changes made since last reset */
  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#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 */
................................................................................
  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 */

/*
** Structure used to store the context required by the 
** sqlite3_preupdate_*() API functions.
*/
struct PreUpdate {
  Vdbe *v;
................................................................................
/*
** The hashing function.
*/
static unsigned int strHash(const char *z){
  unsigned int h = 0;
  unsigned char c;
  while( (c = (unsigned char)*z++)!=0 ){     /*OPTIMIZATION-IF-TRUE*/



    h = (h<<3) ^ h ^ sqlite3UpperToLower[c];

  }
  return h;
}


/* Link pNew element into the hash table pH.  If pEntry!=0 then also
** insert pNew into the pEntry hash bucket.
................................................................................
  Pgno pgno,                  /* Page number obtained */
  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
){
  PgHdr *pPgHdr;
  assert( pPage!=0 );
  pPgHdr = (PgHdr*)pPage->pExtra;
  assert( pPgHdr->pPage==0 );
  memset(pPgHdr, 0, sizeof(PgHdr));
  pPgHdr->pPage = pPage;
  pPgHdr->pData = pPage->pBuf;
  pPgHdr->pExtra = (void *)&pPgHdr[1];
  memset(pPgHdr->pExtra, 0, pCache->szExtra);
  pPgHdr->pCache = pCache;
  pPgHdr->pgno = pgno;
  pPgHdr->flags = PGHDR_CLEAN;
................................................................................
  const void *pKey,   /* Packed key if the btree is an index */
  i64 nKey,           /* Integer key for tables.  Size of pKey for indices */
  int bias,           /* Bias search to the high end */
  int *pRes           /* Write search results here */
){
  int rc;                    /* Status code */
  UnpackedRecord *pIdxKey;   /* Unpacked index key */
  char aSpace[200];          /* Temp space for pIdxKey - to avoid a malloc */
  char *pFree = 0;

  if( pKey ){
    assert( nKey==(i64)(int)nKey );
    pIdxKey = sqlite3VdbeAllocUnpackedRecord(
        pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
    );
................................................................................
    nPayload = pX->nData + pX->nZero;
    pSrc = pX->pData;
    nSrc = pX->nData;
    assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
    nHeader += putVarint32(&pCell[nHeader], nPayload);
    nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
  }else{
    assert( pX->nData==0 );
    assert( pX->nZero==0 );
    assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
    nSrc = nPayload = (int)pX->nKey;
    pSrc = pX->pKey;
    nHeader += putVarint32(&pCell[nHeader], nPayload);
  }
  
  /* Fill in the payload */
................................................................................
** function. If an error occurs while doing so, return 0 and write an 
** error message to pErrorDb.
*/
static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
  int i = sqlite3FindDbName(pDb, zDb);

  if( i==1 ){
    Parse *pParse;
    int rc = 0;
    pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
    if( pParse==0 ){
      sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
      rc = SQLITE_NOMEM_BKPT;
    }else{
      pParse->db = pDb;
      if( sqlite3OpenTempDatabase(pParse) ){
        sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
        rc = SQLITE_ERROR;
      }
      sqlite3DbFree(pErrorDb, pParse->zErrMsg);
      sqlite3ParserReset(pParse);
      sqlite3StackFree(pErrorDb, pParse);
    }
    if( rc ){
      return 0;
    }
  }

  if( i<0 ){
    sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
................................................................................
  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );
  assert( (pMem->flags&MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );


  if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){

    return SQLITE_NOMEM_BKPT;
  }

  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
  ** string representation of the value. Then, if the required encoding
  ** is UTF-16le or UTF-16be do a translation.
  ** 
................................................................................
SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
  if( pMem->flags & MEM_Null ) return;
  switch( aff ){
    case SQLITE_AFF_BLOB: {   /* Really a cast to BLOB */
      if( (pMem->flags & MEM_Blob)==0 ){
        sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
        assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
        MemSetTypeFlag(pMem, MEM_Blob);
      }else{
        pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
      }
      break;
    }
    case SQLITE_AFF_NUMERIC: {
      sqlite3VdbeMemNumerify(pMem);
................................................................................
  int op;
  char *zVal = 0;
  sqlite3_value *pVal = 0;
  int negInt = 1;
  const char *zNeg = "";
  int rc = SQLITE_OK;

  if( !pExpr ){
    *ppVal = 0;
    return SQLITE_OK;
  }
  while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
  if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;

  /* Compressed expressions only appear when parsing the DEFAULT clause
  ** on a table column definition, and hence only when pCtx==0.  This
  ** check ensures that an EP_TokenOnly expression is never passed down
  ** into valueFromFunction(). */
................................................................................
SQLITE_PRIVATE int sqlite3ValueFromExpr(
  sqlite3 *db,              /* The database connection */
  Expr *pExpr,              /* The expression to evaluate */
  u8 enc,                   /* Encoding to use */
  u8 affinity,              /* Affinity to use */
  sqlite3_value **ppVal     /* Write the new value here */
){
  return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
}

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** The implementation of the sqlite_record() function. This function accepts
** a single argument of any type. The return value is a formatted database 
** record (a blob) containing the argument value.
................................................................................

/*
** Create a new virtual database engine.
*/
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
  sqlite3 *db = pParse->db;
  Vdbe *p;
  p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
  if( p==0 ) return 0;

  p->db = db;
  if( db->pVdbe ){
    db->pVdbe->pPrev = p;
  }
  p->pNext = db->pVdbe;
  p->pPrev = 0;
  db->pVdbe = p;
................................................................................
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  pOp->zComment = 0;
#endif
#ifdef SQLITE_DEBUG
  if( p->db->flags & SQLITE_VdbeAddopTrace ){
    int jj, kk;
    Parse *pParse = p->pParse;
    for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
      struct yColCache *x = pParse->aColCache + jj;
      if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
      printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
      kk++;
    }
    if( kk ) printf("\n");
    sqlite3VdbePrintOp(0, i, &p->aOp[i]);
    test_addop_breakpoint();
  }
................................................................................
  int j = ADDR(x);
  assert( v->magic==VDBE_MAGIC_INIT );
  assert( j<p->nLabel );
  assert( j>=0 );
  if( p->aLabel ){
    p->aLabel[j] = v->nOp;
  }
  p->iFixedOp = v->nOp - 1;
}

/*
** Mark the VDBE as one that can only be run one time.
*/
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
  p->runOnlyOnce = 1;
................................................................................
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p2 = val;
}
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p3 = val;
}
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){

  if( !p->db->mallocFailed ) p->aOp[p->nOp-1].p5 = p5;
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  p->pParse->iFixedOp = p->nOp - 1;
  sqlite3VdbeChangeP2(p, addr, p->nOp);
}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
................................................................................
}

/*
** 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 ){
    return sqlite3VdbeChangeToNoop(p, p->nOp-1);
  }else{
    return 0;
  }
}

/*
................................................................................
  fprintf(pOut, zFormat1, pc, 
      sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
      zCom
  );
  fflush(pOut);
}
#endif
















/*
** Release an array of N Mem elements
*/
static void releaseMemArray(Mem *p, int N){
  if( p && N ){
    Mem *pEnd = &p[N];
................................................................................
    if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
      assert( p->db->mallocFailed );
      return SQLITE_ERROR;
    }
    pMem->flags = MEM_Str|MEM_Term;
    zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
    if( zP4!=pMem->z ){

      sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
    }else{
      assert( pMem->z!=0 );
      pMem->n = sqlite3Strlen30(pMem->z);
      pMem->enc = SQLITE_UTF8;
    }
    pMem++;
................................................................................
** running it.
*/
SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
  int i;
#endif
  assert( p!=0 );
  assert( p->magic==VDBE_MAGIC_INIT );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );

  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
  p->magic = VDBE_MAGIC_RUN;
................................................................................
  ** of the prepared statement.
  */
  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode memory used */
  x.pSpace = &((u8*)p->aOp)[n];               /* Unused opcode memory */
  assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
  x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
  assert( x.nFree>=0 );
  if( x.nFree>0 ){
    memset(x.pSpace, 0, x.nFree);
    assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
  }

  resolveP2Values(p, &nArg);
  p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
  if( pParse->explain && nMem<10 ){
    nMem = 10;
  }
  p->expired = 0;
................................................................................
    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
    if( x.nNeeded==0 ) break;
    x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
    x.nFree = x.nNeeded;
  }while( !db->mallocFailed );

  p->nCursor = nCursor;
  if( p->aVar ){
    p->nVar = (ynVar)nVar;
    for(n=0; n<nVar; n++){
      p->aVar[n].flags = MEM_Null;
      p->aVar[n].db = db;
    }
  }
  p->nzVar = pParse->nzVar;
  p->azVar = pParse->azVar;
  pParse->nzVar =  0;
  pParse->azVar = 0;
  if( p->aMem ){



    p->nMem = nMem;
    for(n=0; n<nMem; n++){
      p->aMem[n].flags = MEM_Undefined;
      p->aMem[n].db = db;
    }









  }
  p->explain = pParse->explain;
  sqlite3VdbeRewind(p);
}

/*
** Close a VDBE cursor and release all the resources that cursor 
** happens to hold.
*/
................................................................................
  int n;
  sqlite3 *db = p->db;

  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  sqlite3DbFree(db, p->aColName);
  n = nResColumn*COLNAME_N;
  p->nResColumn = (u16)nResColumn;
  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    pColName->flags = MEM_Null;
    pColName->db = p->db;
    pColName++;
  }
}

/*
** Set the name of the idx'th column to be returned by the SQL statement.
** zName must be a pointer to a nul terminated string.
**
** This call must be made after a call to sqlite3VdbeSetNumCols().
................................................................................
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif
  p->iCurrentTime = 0;
  p->magic = VDBE_MAGIC_INIT;
  return p->rc & db->errMask;
}
 
/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** the result code.  Write any error message text into *pzErrMsg.
*/
................................................................................
** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
** the database connection and frees the object itself.
*/
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
  SubProgram *pSub, *pNext;
  int i;
  assert( p->db==0 || p->db==db );
  releaseMemArray(p->aVar, p->nVar);
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  for(pSub=p->pProgram; pSub; pSub=pNext){
    pNext = pSub->pNext;
    vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
    sqlite3DbFree(db, pSub);
  }


  for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  sqlite3DbFree(db, p->azVar);


  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
}
................................................................................
}

/*
** Return true if the prepared statement is in need of being reset.
*/
SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
  Vdbe *v = (Vdbe*)pStmt;
  return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
}

/*
** 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.
................................................................................
case OP_Null: {           /* out2 */
  int cnt;
  u16 nullFlag;
  pOut = out2Prerelease(p, pOp);
  cnt = pOp->p3-pOp->p2;
  assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
  pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;

  while( cnt>0 ){
    pOut++;
    memAboutToChange(p, pOut);
    sqlite3VdbeMemSetNull(pOut);
    pOut->flags = nullFlag;

    cnt--;
  }
  break;
}

/* Opcode: SoftNull P1 * * * *
** Synopsis: r[P1]=NULL
................................................................................
  rc = ExpandBlob(pIn2);
  if( rc ) goto abort_due_to_error;
  if( pOp->opcode==OP_SorterInsert ){
    rc = sqlite3VdbeSorterWrite(pC, pIn2);
  }else{
    x.nKey = pIn2->n;
    x.pKey = pIn2->z;
    x.nData = 0;
    x.nZero = 0;
    x.pData = 0;
    rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3, 
        ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
        );
    assert( pC->deferredMoveto==0 );
    pC->cacheStatus = CACHE_STALE;
  }
  if( rc) goto abort_due_to_error;
................................................................................
      const char *zColumn;
      const char *zTable;
      const char *zDb;
      Expr *pRight;

      /* if( pSrcList==0 ) break; */
      notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
      /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/
      pRight = pExpr->pRight;
      if( pRight->op==TK_ID ){
        zDb = 0;
        zTable = pExpr->pLeft->u.zToken;
        zColumn = pRight->u.zToken;
      }else{
        assert( pRight->op==TK_DOT );
................................................................................
      int is_agg = 0;             /* True if is an aggregate function */
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      u8 enc = ENC(pParse->db);   /* The database encoding */

      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
      notValid(pParse, pNC, "functions", NC_PartIdx);
      zId = pExpr->u.zToken;
      nId = sqlite3Strlen30(zId);
      pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;
................................................................................
          ** constant because they are constant for the duration of one query */
          ExprSetProperty(pExpr,EP_ConstFunc);
        }
        if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
          /* Date/time functions that use 'now', and other functions like
          ** sqlite_version() that might change over time cannot be used
          ** in an index. */
          notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr);

        }
      }
      if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
        sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
        pNC->nErr++;
        is_agg = 0;
      }else if( no_such_func && pParse->db->init.busy==0
................................................................................
** Special case:  If op==TK_INTEGER and pToken points to a string that
** can be translated into a 32-bit integer, then the token is not
** stored in u.zToken.  Instead, the integer values is written
** into u.iValue and the EP_IntValue flag is set.  No extra storage
** is allocated to hold the integer text and the dequote flag is ignored.
*/
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
  sqlite3 *db,            /* Handle for sqlite3DbMallocZero() (may be null) */
  int op,                 /* Expression opcode */
  const Token *pToken,    /* Token argument.  Might be NULL */
  int dequote             /* True to dequote */
){
  Expr *pNew;
  int nExtra = 0;
  int iValue = 0;
................................................................................
** the SQL statement comes from an external source.
**
** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
** as the previous instance of the same wildcard.  Or if this is the first
** instance of the wildcard, the next sequential variable number is
** assigned.
*/
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
  sqlite3 *db = pParse->db;
  const char *z;

  if( pExpr==0 ) return;
  assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
  z = pExpr->u.zToken;
  assert( z!=0 );
  assert( z[0]!=0 );

  if( z[1]==0 ){
    /* Wildcard of the form "?".  Assign the next variable number */
    assert( z[0]=='?' );
    pExpr->iColumn = (ynVar)(++pParse->nVar);
  }else{
    ynVar x = 0;
    u32 n = sqlite3Strlen30(z);
    if( z[0]=='?' ){
      /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
      ** use it as the variable number */
      i64 i;
      int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
      pExpr->iColumn = x = (ynVar)i;
      testcase( i==0 );
      testcase( i==1 );
      testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
      testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
      if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
        sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
            db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
        x = 0;
      }
      if( i>pParse->nVar ){
        pParse->nVar = (int)i;
      }
    }else{
      /* Wildcards like ":aaa", "$aaa" or "@aaa".  Reuse the same variable
      ** number as the prior appearance of the same name, or if the name
      ** has never appeared before, reuse the same variable number
      */
      ynVar i;
      for(i=0; i<pParse->nzVar; i++){
        if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
          pExpr->iColumn = x = (ynVar)i+1;
          break;
        }
      }
      if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
    }
    if( x>0 ){
      if( x>pParse->nzVar ){
        char **a;
        a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
        if( a==0 ){
          assert( db->mallocFailed ); /* Error reported through mallocFailed */
          return;
        }
        pParse->azVar = a;
        memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
        pParse->nzVar = x;
      }
      if( z[0]!='?' || pParse->azVar[x-1]==0 ){
        sqlite3DbFree(db, pParse->azVar[x-1]);
        pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
      }
    }
  } 
  if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
    sqlite3ErrorMsg(pParse, "too many SQL variables");
  }
}

/*
** Recursively delete an expression tree.
*/
................................................................................
        codeReal(v, z, negFlag, iMem);
      }
#endif
    }
  }
}

#if defined(SQLITE_DEBUG)
/*
** Verify the consistency of the column cache

*/
static int cacheIsValid(Parse *pParse){
  int i, n;
  for(i=n=0; i<SQLITE_N_COLCACHE; i++){
    if( pParse->aColCache[i].iReg>0 ) n++;
  }
  return n==pParse->nColCache;
}
#endif

/*
** Clear a cache entry.
*/
static void cacheEntryClear(Parse *pParse, struct yColCache *p){
  if( p->tempReg ){
    if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
      pParse->aTempReg[pParse->nTempReg++] = p->iReg;
    }
    p->tempReg = 0;
  }
  p->iReg = 0;
  pParse->nColCache--;
  assert( pParse->db->mallocFailed || cacheIsValid(pParse) );



}


/*
** Record in the column cache that a particular column from a
** particular table is stored in a particular register.
*/
................................................................................

  /* First replace any existing entry.
  **
  ** Actually, the way the column cache is currently used, we are guaranteed
  ** that the object will never already be in cache.  Verify this guarantee.
  */
#ifndef NDEBUG
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
  }
#endif

  /* Find an empty slot and replace it */
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    if( p->iReg==0 ){
      p->iLevel = pParse->iCacheLevel;
      p->iTable = iTab;
      p->iColumn = iCol;
      p->iReg = iReg;
      p->tempReg = 0;
      p->lru = pParse->iCacheCnt++;
      pParse->nColCache++;
      assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
      return;
    }
  }

  /* Replace the last recently used */
  minLru = 0x7fffffff;
  idxLru = -1;
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    if( p->lru<minLru ){
      idxLru = i;
      minLru = p->lru;
    }
  }
  if( ALWAYS(idxLru>=0) ){
    p = &pParse->aColCache[idxLru];





    p->iLevel = pParse->iCacheLevel;
    p->iTable = iTab;
    p->iColumn = iCol;
    p->iReg = iReg;
    p->tempReg = 0;
    p->lru = pParse->iCacheCnt++;
    assert( cacheIsValid(pParse) );
    return;
  }
}

/*
** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
** Purge the range of registers from the column cache.
*/
SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
  struct yColCache *p;
  if( iReg<=0 || pParse->nColCache==0 ) return;
  p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
  while(1){
    if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);

    if( p==pParse->aColCache ) break;
    p--;


  }
}

/*
** Remember the current column cache context.  Any new entries added
** added to the column cache after this call are removed when the
** corresponding pop occurs.
................................................................................

/*
** Remove from the column cache any entries that were added since the
** the previous sqlite3ExprCachePush operation.  In other words, restore
** the cache to the state it was in prior the most recent Push.
*/
SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
  int i;
  struct yColCache *p;
  assert( pParse->iCacheLevel>=1 );
  pParse->iCacheLevel--;
#ifdef SQLITE_DEBUG
  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
    printf("POP  to %d\n", pParse->iCacheLevel);
  }
#endif
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    if( p->iReg && p->iLevel>pParse->iCacheLevel ){
      cacheEntryClear(pParse, p);


    }
  }
}

/*
** When a cached column is reused, make sure that its register is
** no longer available as a temp register.  ticket #3879:  that same
** register might be in the cache in multiple places, so be sure to
** get them all.
*/
static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
  int i;
  struct yColCache *p;
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    if( p->iReg==iReg ){
      p->tempReg = 0;
    }
  }
}

/* Generate code that will load into register regOut a value that is
................................................................................
  int iReg,        /* Store results here */
  u8 p5            /* P5 value for OP_Column + FLAGS */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  struct yColCache *p;

  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){
      p->lru = pParse->iCacheCnt++;
      sqlite3ExprCachePinRegister(pParse, p->iReg);
      return p->iReg;
    }
  }  
  assert( v!=0 );
  sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
................................................................................


/*
** Clear all column cache entries.
*/
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
  int i;
  struct yColCache *p;

#if SQLITE_DEBUG
  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
    printf("CLEAR\n");
  }
#endif
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    if( p->iReg ){
      cacheEntryClear(pParse, p);


    }
  }

}

/*
** Record the fact that an affinity change has occurred on iCount
** registers starting with iStart.
*/
SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
................................................................................
**
** This routine is used within assert() and testcase() macros only
** and does not appear in a normal build.
*/
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
  int i;
  struct yColCache *p;
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    int r = p->iReg;
    if( r>=iFrom && r<=iTo ) return 1;    /*NO_TEST*/
  }
  return 0;
}
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */

................................................................................
** the deallocation is deferred until the column cache line that uses
** the register becomes stale.
*/
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
  if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
    int i;
    struct yColCache *p;
    for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
      if( p->iReg==iReg ){
        p->tempReg = 1;
        return;
      }
    }
    pParse->aTempReg[pParse->nTempReg++] = iReg;
  }
................................................................................
  /* Begin by generating some termination code at the end of the
  ** vdbe program
  */
  v = sqlite3GetVdbe(pParse);
  assert( !pParse->isMultiWrite 
       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
  if( v ){
    while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
    sqlite3VdbeAddOp0(v, OP_Halt);

#if SQLITE_USER_AUTHENTICATION
    if( pParse->nTableLock>0 && db->init.busy==0 ){
      sqlite3UserAuthInit(db);
      if( db->auth.authLevel<UAUTH_User ){
        sqlite3ErrorMsg(pParse, "user not authenticated");
................................................................................
    if( db->mallocFailed==0 
     && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
    ){
      int iDb, i;
      assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
      sqlite3VdbeJumpHere(v, 0);
      for(iDb=0; iDb<db->nDb; iDb++){

        if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
        sqlite3VdbeUsesBtree(v, iDb);

        sqlite3VdbeAddOp4Int(v,
          OP_Transaction,                    /* Opcode */
          iDb,                               /* P1 */
          DbMaskTest(pParse->writeMask,iDb), /* P2 */
          pParse->cookieValue[iDb],          /* P3 */
          db->aDb[iDb].pSchema->iGeneration  /* P4 */
        );
        if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
        VdbeComment((v,
              "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
      }
#ifndef SQLITE_OMIT_VIRTUALTABLE
      for(i=0; i<pParse->nVtabLock; i++){
................................................................................
    *  See ticket [a696379c1f08866] */
    if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
    sqlite3VdbeMakeReady(v, pParse);
    pParse->rc = SQLITE_DONE;
  }else{
    pParse->rc = SQLITE_ERROR;
  }

  /* We are done with this Parse object. There is no need to de-initialize it */
#if 0
  pParse->colNamesSet = 0;
  pParse->nTab = 0;
  pParse->nMem = 0;
  pParse->nSet = 0;
  pParse->nVar = 0;
  DbMaskZero(pParse->cookieMask);
#endif
}

/*
** Run the parser and code generator recursively in order to generate
** code for the SQL statement given onto the end of the pParse context
** currently under construction.  When the parser is run recursively
** this way, the final OP_Halt is not appended and other initialization
................................................................................
** care if you decide to try to use this routine for some other purposes.
*/
SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  char *zErrMsg = 0;
  sqlite3 *db = pParse->db;
# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
  char saveBuf[SAVE_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(db, zFormat, ap);
  va_end(ap);
  if( zSql==0 ){
    return;   /* A malloc must have failed */
  }
  pParse->nested++;
  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
  memset(&pParse->nVar, 0, SAVE_SZ);
  sqlite3RunParser(pParse, zSql, &zErrMsg);
  sqlite3DbFree(db, zErrMsg);
  sqlite3DbFree(db, zSql);
  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
  pParse->nested--;
}

#if SQLITE_USER_AUTHENTICATION
/*
** Return TRUE if zTable is the name of the system table that stores the
** list of users and their access credentials.
................................................................................
** Record the fact that the schema cookie will need to be verified
** for database iDb.  The code to actually verify the schema cookie
** will occur at the end of the top-level VDBE and will be generated
** later, by sqlite3FinishCoding().
*/
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  sqlite3 *db = pToplevel->db;

  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pBt!=0 || iDb==1 );
  assert( iDb<SQLITE_MAX_ATTACHED+2 );
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
    DbMaskSet(pToplevel->cookieMask, iDb);
    pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
    if( !OMIT_TEMPDB && iDb==1 ){
      sqlite3OpenTempDatabase(pToplevel);
    }
  }
}

/*
................................................................................
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }
  if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
  sqlite3ReleaseTempReg(pParse, regRowid);
  sqlite3ReleaseTempReg(pParse, regData);
  if( emptyDestTest ){

    sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
    sqlite3VdbeJumpHere(v, emptyDestTest);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
    return 0;
  }else{
    return 1;
  }
................................................................................
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
  Vdbe *pReprepare,         /* VM being reprepared */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  Parse *pParse;            /* Parsing context */
  char *zErrMsg = 0;        /* Error message */
  int rc = SQLITE_OK;       /* Result code */
  int i;                    /* Loop counter */

  /* Allocate the parsing context */
  pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
  if( pParse==0 ){
    rc = SQLITE_NOMEM_BKPT;
    goto end_prepare;
  }


  pParse->pReprepare = pReprepare;
  assert( ppStmt && *ppStmt==0 );
  /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
  assert( sqlite3_mutex_held(db->mutex) );

  /* Check to verify that it is possible to get a read lock on all
  ** database schemas.  The inability to get a read lock indicates that
  ** some other database connection is holding a write-lock, which in
................................................................................
        goto end_prepare;
      }
    }
  }

  sqlite3VtabUnlockList(db);

  pParse->db = db;
  pParse->nQueryLoop = 0;  /* Logarithmic, so 0 really means 1 */
  if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
    char *zSqlCopy;
    int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
    testcase( nBytes==mxLen );
    testcase( nBytes==mxLen+1 );
    if( nBytes>mxLen ){
      sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long");
      rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
      goto end_prepare;
    }
    zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
    if( zSqlCopy ){
      sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
      pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
      sqlite3DbFree(db, zSqlCopy);
    }else{
      pParse->zTail = &zSql[nBytes];
    }
  }else{
    sqlite3RunParser(pParse, zSql, &zErrMsg);
  }
  assert( 0==pParse->nQueryLoop );

  if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
  if( pParse->checkSchema ){
    schemaIsValid(pParse);
  }
  if( db->mallocFailed ){
    pParse->rc = SQLITE_NOMEM_BKPT;
  }
  if( pzTail ){
    *pzTail = pParse->zTail;
  }
  rc = pParse->rc;

#ifndef SQLITE_OMIT_EXPLAIN
  if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
    static const char * const azColName[] = {
       "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
       "selectid", "order", "from", "detail"
    };
    int iFirst, mx;
    if( pParse->explain==2 ){
      sqlite3VdbeSetNumCols(pParse->pVdbe, 4);
      iFirst = 8;
      mx = 12;
    }else{
      sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
      iFirst = 0;
      mx = 8;
    }
    for(i=iFirst; i<mx; i++){
      sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
                            azColName[i], SQLITE_STATIC);
    }
  }
#endif

  if( db->init.busy==0 ){
    Vdbe *pVdbe = pParse->pVdbe;
    sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
  }
  if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
    sqlite3VdbeFinalize(pParse->pVdbe);
    assert(!(*ppStmt));
  }else{
    *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
  }

  if( zErrMsg ){
    sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
    sqlite3DbFree(db, zErrMsg);
  }else{
    sqlite3Error(db, rc);
  }

  /* Delete any TriggerPrg structures allocated while parsing this statement. */
  while( pParse->pTriggerPrg ){
    TriggerPrg *pT = pParse->pTriggerPrg;
    pParse->pTriggerPrg = pT->pNext;
    sqlite3DbFree(db, pT);
  }

end_prepare:

  sqlite3ParserReset(pParse);
  sqlite3StackFree(db, pParse);
  rc = sqlite3ApiExit(db, rc);
  assert( (rc&db->errMask)==rc );
  return rc;
}
static int sqlite3LockAndPrepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
................................................................................

/*
** Allocate a KeyInfo object sufficient for an index of N key columns and
** X extra columns.
*/
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
  int nExtra = (N+X)*(sizeof(CollSeq*)+1);
  KeyInfo *p = sqlite3DbMallocRaw(db, sizeof(KeyInfo) + nExtra);
  if( p ){
    p->aSortOrder = (u8*)&p->aColl[N+X];
    p->nField = (u16)N;
    p->nXField = (u16)X;
    p->enc = ENC(db);
    p->db = db;
    p->nRef = 1;
................................................................................
**
** The number of terms in a join is limited by the number of bits
** in prereqRight and prereqAll.  The default is 64 bits, hence SQLite
** is only able to process joins with 64 or fewer tables.
*/
struct WhereTerm {
  Expr *pExpr;            /* Pointer to the subexpression that is this term */






  int iParent;            /* Disable pWC->a[iParent] when this term disabled */
  int leftCursor;         /* Cursor number of X in "X <op> <expr>" */
  int iField;             /* Field in (?,?,?) IN (SELECT...) vector */
  union {
    int leftColumn;         /* Column number of X in "X <op> <expr>" */
    WhereOrInfo *pOrInfo;   /* Extra information if (eOperator & WO_OR)!=0 */
    WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
  } u;
  LogEst truthProb;       /* Probability of truth for this expression */
  u16 eOperator;          /* A WO_xx value describing <op> */
  u16 wtFlags;            /* TERM_xxx bit flags.  See below */
  u8 nChild;              /* Number of children that must disable us */
  u8 eMatchOp;            /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
  WhereClause *pWC;       /* The clause this term is part of */
  Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */
};

/*
** Allowed values of WhereTerm.wtFlags
*/
................................................................................
** planner.
*/
struct WhereInfo {
  Parse *pParse;            /* Parsing and code generating context */
  SrcList *pTabList;        /* List of tables in the join */
  ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
  ExprList *pDistinctSet;   /* DISTINCT over all these values */
  WhereLoop *pLoops;        /* List of all WhereLoop objects */
  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
  LogEst nRowOut;           /* Estimated number of output rows */
  LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */




  u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */

  i8 nOBSat;                /* Number of ORDER BY terms satisfied by indices */
  u8 sorted;                /* True if really sorted (not just grouped) */
  u8 eOnePass;              /* ONEPASS_OFF, or _SINGLE, or _MULTI */
  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values */
  u8 nLevel;                /* Number of nested loop */
  u8 bOrderedInnerLoop;     /* True if only the inner-most loop is ordered */
  int iTop;                 /* The very beginning of the WHERE loop */

  int iContinue;            /* Jump here to continue with next record */
  int iBreak;               /* Jump here to break out of the loop */
  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
  int aiCurOnePass[2];      /* OP_OpenWrite cursors for the ONEPASS opt */
  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
  WhereClause sWC;          /* Decomposition of the WHERE clause */
  WhereLevel a[1];          /* Information about each nest loop in WHERE */
};

/*
** Private interfaces - callable only by other where.c routines.
**
** where.c:
................................................................................
** to the pRight values. This function modifies characters within the
** affinity string to SQLITE_AFF_BLOB if either:
**
**   * the comparison will be performed with no affinity, or
**   * the affinity change in zAff is guaranteed not to change the value.
*/
static void updateRangeAffinityStr(
  Parse *pParse,                  /* Parse context */
  Expr *pRight,                   /* RHS of comparison */
  int n,                          /* Number of vector elements in comparison */
  char *zAff                      /* Affinity string to modify */
){
  int i;
  for(i=0; i<n; i++){
    Expr *p = sqlite3VectorFieldSubexpr(pRight, i);
................................................................................
        testcase( bRev );
        testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
        assert( (bRev & ~1)==0 );
        pLevel->iLikeRepCntr <<=1;
        pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
      }
#endif
      if( pRangeStart==0
       && (j = pIdx->aiColumn[nEq])>=0 
       && pIdx->pTable->aCol[j].notNull==0
      ){
        bSeekPastNull = 1;

      }
    }
    assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );

    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).
................................................................................
      if( (pRangeStart->wtFlags & TERM_VNULL)==0
       && sqlite3ExprCanBeNull(pRight)
      ){
        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
        VdbeCoverage(v);
      }
      if( zStartAff ){
        updateRangeAffinityStr(pParse, pRight, nBtm, &zStartAff[nEq]);
      }  
      nConstraint += nBtm;
      testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
      if( sqlite3ExprIsVector(pRight)==0 ){
        disableTerm(pLevel, pRangeStart);
      }else{
        startEq = 1;
................................................................................
      if( (pRangeEnd->wtFlags & TERM_VNULL)==0
       && sqlite3ExprCanBeNull(pRight)
      ){
        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
        VdbeCoverage(v);
      }
      if( zEndAff ){
        updateRangeAffinityStr(pParse, pRight, nTop, zEndAff);
        codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
      }else{
        assert( pParse->db->mallocFailed );
      }
      nConstraint += nTop;
      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );

................................................................................
  **
  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
  ** and we are coding the t1 loop and the t2 loop has not yet coded,
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
  ** the implied "t1.a=123" constraint.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE, *pEAlt;
    WhereTerm *pAlt;
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
    if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
................................................................................
                    WO_EQ|WO_IN|WO_IS, 0);
    if( pAlt==0 ) continue;
    if( pAlt->wtFlags & (TERM_CODED) ) continue;
    testcase( pAlt->eOperator & WO_EQ );
    testcase( pAlt->eOperator & WO_IS );
    testcase( pAlt->eOperator & WO_IN );
    VdbeModuleComment((v, "begin transitive constraint"));
    pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
    if( pEAlt ){
      *pEAlt = *pAlt->pExpr;
      pEAlt->pLeft = pE->pLeft;
      sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
      sqlite3StackFree(db, pEAlt);
    }
  }

  /* For a LEFT OUTER JOIN, generate code that will record the fact that
  ** at least one row of the right table has matched the left table.  
  */
  if( pLevel->iLeftJoin ){
    pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
................................................................................
      return 0;
    }
    memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
    if( pOld!=pWC->aStatic ){
      sqlite3DbFree(db, pOld);
    }
    pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
    memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
  }
  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;


  return idx;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL"
................................................................................
** and the index:
**
**   CREATE INDEX ... ON (a, b, c, d, e)
**
** then this function would be invoked with nEq=1. The value returned in
** this case is 3.
*/
int whereRangeVectorLen(
  Parse *pParse,       /* Parsing context */
  int iCur,            /* Cursor open on pIdx */
  Index *pIdx,         /* The index to be used for a inequality constraint */
  int nEq,             /* Number of prior equality constraints on same index */
  WhereTerm *pTerm     /* The vector inequality constraint */
){
  int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft);
................................................................................
          }else{
            rev = revIdx ^ pOrderBy->a[i].sortOrder;
            if( rev ) *pRevMask |= MASKBIT(iLoop);
            revSet = 1;
          }
        }
        if( isMatch ){
          if( iColumn<0 ){
            testcase( distinctColumns==0 );
            distinctColumns = 1;
          }
          obSat |= MASKBIT(i);
        }else{
          /* No match found */
          if( j==0 || j<nKeyCol ){
................................................................................
      if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
        pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
      }
    }else{
      pWInfo->nOBSat = pFrom->isOrdered;
      pWInfo->revMask = pFrom->revLoop;
      if( pWInfo->nOBSat<=0 ){

        pWInfo->nOBSat = 0;
        if( nLoop>0 && (pFrom->aLoop[nLoop-1]->wsFlags & WHERE_ONEROW)==0 ){


          Bitmask m = 0;
          int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
                      WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);


          if( rc==pWInfo->pOrderBy->nExpr ){
            pWInfo->bOrderedInnerLoop = 1;
            pWInfo->revMask = m;
          }
        }
      }
    }
................................................................................
  ** return value. A single allocation is used to store the WhereInfo
  ** struct, the contents of WhereInfo.a[], the WhereClause structure
  ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
  ** field (type Bitmask) it must be aligned on an 8-byte boundary on
  ** some architectures. Hence the ROUND8() below.
  */
  nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
  pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
  if( db->mallocFailed ){
    sqlite3DbFree(db, pWInfo);
    pWInfo = 0;
    goto whereBeginError;
  }
  pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
  pWInfo->nLevel = nTabList;
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->pOrderBy = pOrderBy;
  pWInfo->pDistinctSet = pDistinctSet;


  pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
  pWInfo->wctrlFlags = wctrlFlags;
  pWInfo->iLimit = iAuxArg;
  pWInfo->savedNQueryLoop = pParse->nQueryLoop;



  assert( pWInfo->eOnePass==ONEPASS_OFF );  /* ONEPASS defaults to OFF */
  pMaskSet = &pWInfo->sMaskSet;
  sWLB.pWInfo = pWInfo;
  sWLB.pWC = &pWInfo->sWC;
  sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
  assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
  whereLoopInit(sWLB.pNew);
................................................................................
  if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf;
}
  yymsp[0].minor.yy190 = yylhsminor.yy190;
        break;
      case 159: /* expr ::= VARIABLE */
{
  if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){

    spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr);
  }else{
    /* When doing a nested parse, one can include terms in an expression
    ** that look like this:   #1 #2 ...  These terms refer to registers
    ** in the virtual machine.  #N is the N-th register. */
    Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
    assert( t.n>=2 );
    spanSet(&yymsp[0].minor.yy190, &t, &t);
................................................................................
          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
             yyTracePrompt,yyTokenName[yymajor]);
        }
#endif
        yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
        yymajor = YYNOCODE;
      }else{
        while( yypParser->yytos >= &yypParser->yystack
            && yymx != YYERRORSYMBOL
            && (yyact = yy_find_reduce_action(
                        yypParser->yytos->stateno,
                        YYERRORSYMBOL)) >= YY_MIN_REDUCE
        ){
          yy_pop_parser_stack(yypParser);
        }
................................................................................
static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
  const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
  char *zSql;
  sqlite3_stmt *p;
  int rc;
  i64 nRow = 0;

  if( sqlite3_table_column_metadata(db,pRtree->zDb,"sqlite_stat1",
          0,0,0,0,0,0)==SQLITE_ERROR ){


    pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
    return SQLITE_OK;

  }
  zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
  if( zSql==0 ){
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
    if( rc==SQLITE_OK ){
................................................................................
          fprintf(fts5yyTraceFILE,"%sDiscard input token %s\n",
             fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
        }
#endif
        fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
        fts5yymajor = fts5YYNOCODE;
      }else{
        while( fts5yypParser->fts5yytos >= &fts5yypParser->fts5yystack
            && fts5yymx != fts5YYERRORSYMBOL
            && (fts5yyact = fts5yy_find_reduce_action(
                        fts5yypParser->fts5yytos->stateno,
                        fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
        ){
          fts5yy_pop_parser_stack(fts5yypParser);
        }
................................................................................
  int tflags,                     /* Mask of FTS5_TOKEN_* flags */
  const char *pToken,             /* Buffer containing token */
  int nToken,                     /* Size of token in bytes */
  int iStartOff,                  /* Start offset of token */
  int iEndOff                     /* End offset of token */
){
  int rc = SQLITE_OK;




  if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
    Fts5SFinder *p = (Fts5SFinder*)pContext;
    if( p->iPos>0 ){
      int i;
      char c = 0;
      for(i=iStartOff-1; i>=0; i--){
................................................................................

        if( rc==SQLITE_OK && sFinder.nFirst && nDocsize>nToken ){
          for(jj=0; jj<(sFinder.nFirst-1); jj++){
            if( sFinder.aFirst[jj+1]>io ) break;
          }

          if( sFinder.aFirst[jj]<io ){
            int nScore;
            memset(aSeen, 0, nPhrase);
            rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i, 
              sFinder.aFirst[jj], nToken, &nScore, 0
            );

            nScore += (sFinder.aFirst[jj]==0 ? 120 : 100);
            if( rc==SQLITE_OK && nScore>nBestScore ){
................................................................................
static void fts5SourceIdFunc(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "fts5: 2016-09-16 17:50:57 e3d9efa2770cd789ece3f4db4941b901c8b805ad", -1, SQLITE_TRANSIENT);
}

static int fts5Init(sqlite3 *db){
  static const sqlite3_module fts5Mod = {
    /* iVersion      */ 2,
    /* xCreate       */ fts5CreateMethod,
    /* xConnect      */ fts5ConnectMethod,







|







 







<





<


<






<
<
<
<
<
<
<
<




<












<
<









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







 







<











<
<










>
>
>
>
>
>
>
>







 







|







 







|


|



<
<
<







 







|







 







|







 







<
<
<







 







>
>
>
>
>
>







 







<
<
<
<
<







 







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







 







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





<
<
<
<
<

<



|
|
|
|
<





>


<







<


<

<
<
<
<
<
<
<







 







|
|
|
>
|







 







>
>
>
|
>







 







|







 







|







 







<
<







 







|

|
<
<
<
<
|
|
|
|
|
|
|
<
<







 







>







 







|







 







|
<
<
<







 







|







 







|

>







 







|

<







 







<







 







>
|







<







 







|







 







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







 







>







 







|







 







<
<
|
<







 







|



<
<
<
<
<
<
<
<




|
>
>
>
|
<
<
<
|
>
>
>
>
>
>
>
>
>

<







 







|

|
<
<
<
<







 







|







 







<






>
>
|
|
>
>



<







 







|







 







>





>







 







<
<
<







 







<







 







<







 







|
>







 







|







 







|








>





|
<





|







|










|

|



|

|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
<
|







 







<

<
>

<
<
<
<
<
<
<
<
<
<
<
<
|
|

|

<

<

<
>
>
>







 







|
|



|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
|
|
|
|
|
|
<

>
>
>
>
>
|
|
|
|
|
|
<
<
<







|
|
|
<
|
>
|
<
>
>







 







|
<







|
|
|
>
>













|







 







|
|







 







<






|
|
|
>
>


>







 







|







 







|







 







<







 







>


>




|
|







 







<
<
<
<
<
<
<
<
<
<







 







<
|










|
|



|







 







<

|
|

|


<







 







>







 







<



<
|
<
<
<
<
|
>
>
|







 







|
<












|
|


|


|

|

|
|
|


|


|

|


|





|
|



|




|






|
|

|
|


|










|
|
|





|
<







 







|







 







>
>
>
>
>
>








<
<
<
<
<
<







 







<
<
<

>
>
>
>

>





<


>
|
|
|
<

<







 







<







 







|
|
|
<
|
>







 







|







 







|







 







|







 







<
<
|
|
|
<
<







 







<











>
>







 







|







 







|







 







>

|
>
>



>
>







 







|





<
<




>
>




>
>
>







 







>

|







 







|







 







|
|
>
>

<
>







 







|







 







>
>
>







 







<







 







|







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
.....
15513
15514
15515
15516
15517
15518
15519

15520
15521
15522
15523
15524

15525
15526

15527
15528
15529
15530
15531
15532








15533
15534
15535
15536

15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548


15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
.....
15586
15587
15588
15589
15590
15591
15592

15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603


15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
.....
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
.....
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011



17012
17013
17014
17015
17016
17017
17018
.....
17077
17078
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
.....
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174
17175
17176
17177
17178
17179
.....
17725
17726
17727
17728
17729
17730
17731



17732
17733
17734
17735
17736
17737
17738
.....
17799
17800
17801
17802
17803
17804
17805
17806
17807
17808
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
.....
17849
17850
17851
17852
17853
17854
17855





17856
17857
17858
17859
17860
17861
17862
.....
17989
17990
17991
17992
17993
17994
17995












17996
17997
17998
17999
18000
18001
18002
.....
18013
18014
18015
18016
18017
18018
18019
18020
18021
18022
18023
18024
18025
18026
18027
18028
18029
18030
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044





18045

18046
18047
18048
18049
18050
18051
18052

18053
18054
18055
18056
18057
18058
18059
18060

18061
18062
18063
18064
18065
18066
18067

18068
18069

18070







18071
18072
18073
18074
18075
18076
18077
.....
18082
18083
18084
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094
18095
18096
18097
18098
18099
18100
.....
28772
28773
28774
28775
28776
28777
28778
28779
28780
28781
28782
28783
28784
28785
28786
28787
28788
28789
28790
.....
44019
44020
44021
44022
44023
44024
44025
44026
44027
44028
44029
44030
44031
44032
44033
.....
58985
58986
58987
58988
58989
58990
58991
58992
58993
58994
58995
58996
58997
58998
58999
.....
64322
64323
64324
64325
64326
64327
64328


64329
64330
64331
64332
64333
64334
64335
.....
68021
68022
68023
68024
68025
68026
68027
68028
68029
68030




68031
68032
68033
68034
68035
68036
68037


68038
68039
68040
68041
68042
68043
68044
.....
69034
69035
69036
69037
69038
69039
69040
69041
69042
69043
69044
69045
69046
69047
69048
.....
69334
69335
69336
69337
69338
69339
69340
69341
69342
69343
69344
69345
69346
69347
69348
.....
70011
70012
70013
70014
70015
70016
70017
70018



70019
70020
70021
70022
70023
70024
70025
.....
70135
70136
70137
70138
70139
70140
70141
70142
70143
70144
70145
70146
70147
70148
70149
.....
70478
70479
70480
70481
70482
70483
70484
70485
70486
70487
70488
70489
70490
70491
70492
70493
70494
.....
70642
70643
70644
70645
70646
70647
70648
70649
70650

70651
70652
70653
70654
70655
70656
70657
.....
70831
70832
70833
70834
70835
70836
70837

70838
70839
70840
70841
70842
70843
70844
.....
71221
71222
71223
71224
71225
71226
71227
71228
71229
71230
71231
71232
71233
71234
71235
71236

71237
71238
71239
71240
71241
71242
71243
.....
71352
71353
71354
71355
71356
71357
71358
71359
71360
71361
71362
71363
71364
71365
71366
.....
71914
71915
71916
71917
71918
71919
71920
71921
71922
71923
71924
71925
71926
71927
71928
71929
71930
71931
71932
71933
71934
71935
71936
71937
71938
71939
71940
71941
71942
.....
72141
72142
72143
72144
72145
72146
72147
72148
72149
72150
72151
72152
72153
72154
72155
.....
72284
72285
72286
72287
72288
72289
72290
72291
72292
72293
72294
72295
72296
72297
72298
.....
72373
72374
72375
72376
72377
72378
72379


72380

72381
72382
72383
72384
72385
72386
72387
.....
72402
72403
72404
72405
72406
72407
72408
72409
72410
72411
72412








72413
72414
72415
72416
72417
72418
72419
72420
72421



72422
72423
72424
72425
72426
72427
72428
72429
72430
72431
72432

72433
72434
72435
72436
72437
72438
72439
.....
72577
72578
72579
72580
72581
72582
72583
72584
72585
72586




72587
72588
72589
72590
72591
72592
72593
.....
73341
73342
73343
73344
73345
73346
73347
73348
73349
73350
73351
73352
73353
73354
73355
.....
73405
73406
73407
73408
73409
73410
73411

73412
73413
73414
73415
73416
73417
73418
73419
73420
73421
73422
73423
73424
73425
73426

73427
73428
73429
73430
73431
73432
73433
.....
76665
76666
76667
76668
76669
76670
76671
76672
76673
76674
76675
76676
76677
76678
76679
.....
78417
78418
78419
78420
78421
78422
78423
78424
78425
78426
78427
78428
78429
78430
78431
78432
78433
78434
78435
78436
78437
.....
82340
82341
82342
82343
82344
82345
82346



82347
82348
82349
82350
82351
82352
82353
.....
88782
88783
88784
88785
88786
88787
88788

88789
88790
88791
88792
88793
88794
88795
.....
88810
88811
88812
88813
88814
88815
88816

88817
88818
88819
88820
88821
88822
88823
.....
88869
88870
88871
88872
88873
88874
88875
88876
88877
88878
88879
88880
88881
88882
88883
88884
.....
90410
90411
90412
90413
90414
90415
90416
90417
90418
90419
90420
90421
90422
90423
90424
.....
90628
90629
90630
90631
90632
90633
90634
90635
90636
90637
90638
90639
90640
90641
90642
90643
90644
90645
90646
90647
90648
90649
90650

90651
90652
90653
90654
90655
90656
90657
90658
90659
90660
90661
90662
90663
90664
90665
90666
90667
90668
90669
90670
90671
90672
90673
90674
90675
90676
90677
90678
90679
90680
90681
90682
90683
90684
90685
90686
90687
90688
90689
90690
90691
90692
90693
90694
90695

90696
90697
90698

90699
90700
90701
90702
90703
90704
90705
90706
.....
92652
92653
92654
92655
92656
92657
92658

92659

92660
92661












92662
92663
92664
92665
92666

92667

92668

92669
92670
92671
92672
92673
92674
92675
92676
92677
92678
.....
92694
92695
92696
92697
92698
92699
92700
92701
92702
92703
92704
92705
92706








92707






92708
92709
92710
92711
92712
92713
92714
92715

92716
92717
92718
92719
92720
92721
92722
92723
92724
92725
92726
92727



92728
92729
92730
92731
92732
92733
92734
92735
92736
92737

92738
92739
92740

92741
92742
92743
92744
92745
92746
92747
92748
92749
.....
92759
92760
92761
92762
92763
92764
92765
92766

92767
92768
92769
92770
92771
92772
92773
92774
92775
92776
92777
92778
92779
92780
92781
92782
92783
92784
92785
92786
92787
92788
92789
92790
92791
92792
92793
92794
92795
92796
92797
92798
92799
.....
92863
92864
92865
92866
92867
92868
92869
92870
92871
92872
92873
92874
92875
92876
92877
92878
.....
92896
92897
92898
92899
92900
92901
92902

92903
92904
92905
92906
92907
92908
92909
92910
92911
92912
92913
92914
92915
92916
92917
92918
92919
92920
92921
92922
92923
.....
92941
92942
92943
92944
92945
92946
92947
92948
92949
92950
92951
92952
92953
92954
92955
.....
94637
94638
94639
94640
94641
94642
94643
94644
94645
94646
94647
94648
94649
94650
94651
.....
98407
98408
98409
98410
98411
98412
98413

98414
98415
98416
98417
98418
98419
98420
.....
98433
98434
98435
98436
98437
98438
98439
98440
98441
98442
98443
98444
98445
98446
98447
98448
98449
98450
98451
98452
98453
98454
98455
98456
.....
98493
98494
98495
98496
98497
98498
98499










98500
98501
98502
98503
98504
98505
98506
.....
98512
98513
98514
98515
98516
98517
98518

98519
98520
98521
98522
98523
98524
98525
98526
98527
98528
98529
98530
98531
98532
98533
98534
98535
98536
98537
98538
98539
98540
98541
98542
......
102295
102296
102297
102298
102299
102300
102301

102302
102303
102304
102305
102306
102307
102308

102309
102310
102311
102312
102313
102314
102315
......
109513
109514
109515
109516
109517
109518
109519
109520
109521
109522
109523
109524
109525
109526
109527
......
114010
114011
114012
114013
114014
114015
114016

114017
114018
114019

114020




114021
114022
114023
114024
114025
114026
114027
114028
114029
114030
114031
......
114061
114062
114063
114064
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
114101
114102
114103
114104
114105
114106
114107
114108
114109
114110
114111
114112
114113
114114
114115
114116
114117
114118
114119
114120
114121
114122
114123
114124
114125
114126
114127
114128
114129
114130
114131
114132
114133
114134
114135
114136
114137
114138
114139
114140
114141
114142
114143
114144
114145
114146
114147
114148
114149
114150
114151
114152
114153
114154

114155
114156
114157
114158
114159
114160
114161
......
115352
115353
115354
115355
115356
115357
115358
115359
115360
115361
115362
115363
115364
115365
115366
......
124012
124013
124014
124015
124016
124017
124018
124019
124020
124021
124022
124023
124024
124025
124026
124027
124028
124029
124030
124031
124032






124033
124034
124035
124036
124037
124038
124039
......
124178
124179
124180
124181
124182
124183
124184



124185
124186
124187
124188
124189
124190
124191
124192
124193
124194
124195
124196

124197
124198
124199
124200
124201
124202

124203

124204
124205
124206
124207
124208
124209
124210
......
124660
124661
124662
124663
124664
124665
124666

124667
124668
124669
124670
124671
124672
124673
......
125745
125746
125747
125748
125749
125750
125751
125752
125753
125754

125755
125756
125757
125758
125759
125760
125761
125762
125763
......
125799
125800
125801
125802
125803
125804
125805
125806
125807
125808
125809
125810
125811
125812
125813
......
125849
125850
125851
125852
125853
125854
125855
125856
125857
125858
125859
125860
125861
125862
125863
......
126285
126286
126287
126288
126289
126290
126291
126292
126293
126294
126295
126296
126297
126298
126299
......
126303
126304
126305
126306
126307
126308
126309


126310
126311
126312


126313
126314
126315
126316
126317
126318
126319
......
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
......
130001
130002
130003
130004
130005
130006
130007
130008
130009
130010
130011
130012
130013
130014
130015
......
131447
131448
131449
131450
131451
131452
131453
131454
131455
131456
131457
131458
131459
131460
131461
......
131901
131902
131903
131904
131905
131906
131907
131908
131909
131910
131911
131912
131913
131914
131915
131916
131917
131918
131919
131920
131921
131922
131923
131924
......
132190
132191
132192
132193
132194
132195
132196
132197
132198
132199
132200
132201
132202


132203
132204
132205
132206
132207
132208
132209
132210
132211
132212
132213
132214
132215
132216
132217
132218
132219
132220
132221
132222
......
135665
135666
135667
135668
135669
135670
135671
135672
135673
135674
135675
135676
135677
135678
135679
135680
135681
......
136440
136441
136442
136443
136444
136445
136446
136447
136448
136449
136450
136451
136452
136453
136454
......
164297
164298
164299
164300
164301
164302
164303
164304
164305
164306
164307
164308

164309
164310
164311
164312
164313
164314
164315
164316
......
181133
181134
181135
181136
181137
181138
181139
181140
181141
181142
181143
181144
181145
181146
181147
......
181499
181500
181501
181502
181503
181504
181505
181506
181507
181508
181509
181510
181511
181512
181513
181514
181515
......
181658
181659
181660
181661
181662
181663
181664

181665
181666
181667
181668
181669
181670
181671
......
195592
195593
195594
195595
195596
195597
195598
195599
195600
195601
195602
195603
195604
195605
195606
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.15.0"
#define SQLITE_VERSION_NUMBER 3015000
#define SQLITE_SOURCE_ID      "2016-10-12 15:15:30 61f0526978af667781c57bcc87510e4524efd0d8"

/*
** 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
................................................................................
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  u8 okConstFactor;    /* OK to factor out constants */
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 nColCache;        /* Number of entries in aColCache[] */

  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */

  int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
  int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */

  int ckBase;          /* Base register of data during check constraints */
  int iSelfTab;        /* Table of an index whose exprs are being coded */
  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  int nLabel;          /* Number of labels used */
  int *aLabel;         /* Space to hold the labels */








  ExprList *pConstExpr;/* Constant expressions */
  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 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 */


  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  int addrCrTab;       /* Address of OP_CreateTable opcode on CREATE TABLE */
  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* columns referenced */
  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  u8 disableTriggers;  /* True to disable triggers */

  /**************************************************************************
  ** Fields above must be initialized to zero.  The fields that follow,
  ** down to the beginning of the recursive section, do not need to be
  ** initialized as they will be set before being used.  The boundary is
  ** determined by offsetof(Parse,aColCache).
  **************************************************************************/

  struct yColCache {
    int iTable;           /* Table cursor number */
    i16 iColumn;          /* Table column number */
    u8 tempReg;           /* iReg is a temp register that needs to be freed */
    int iLevel;           /* Nesting level */
    int iReg;             /* Reg with value of this column. 0 means none. */
    int lru;              /* Least recently used entry has the smallest value */
  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
  int aTempReg[8];        /* Holding area for temporary registers */
  Token sNameToken;       /* Token with unqualified schema object name */
  Token sLastToken;       /* The last token parsed */

  /************************************************************************
  ** Above is constant between recursions.  Below is reset before and after
  ** each recursion.  The boundary between these two regions is determined
  ** using offsetof(Parse,nVar) so the nVar field must be the first field
  ** in the recursive region.
  ************************************************************************/
................................................................................
  int nzVar;                /* Number of available slots in azVar[] */
  u8 iPkSortOrder;          /* ASC or DESC for INTEGER PRIMARY KEY */
  u8 explain;               /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  u8 declareVtab;           /* True if inside sqlite3_declare_vtab() */
  int nVtabLock;            /* Number of virtual tables to lock */
#endif

  int nHeight;              /* Expression tree height of current sub-select */
#ifndef SQLITE_OMIT_EXPLAIN
  int iSelectId;            /* ID of current select for EXPLAIN output */
  int iNextSelectId;        /* Next available select ID for EXPLAIN output */
#endif
  char **azVar;             /* Pointers to names of parameters */
  Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
  const char *zTail;        /* All SQL text past the last semicolon parsed */
  Table *pNewTable;         /* A table being constructed by CREATE TABLE */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */


#ifndef SQLITE_OMIT_VIRTUALTABLE
  Token sArg;               /* Complete text of a module argument */
  Table **apVtabLock;       /* Pointer to virtual tables needing locking */
#endif
  Table *pZombieTab;        /* List of Table objects to delete after code gen */
  TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
  With *pWith;              /* Current WITH clause, or NULL */
  With *pWithToFree;        /* Free this WITH object at the end of the parse */
};

/*
** Sizes and pointers of various parts of the Parse object.
*/
#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
#define PARSE_RECURSE_SZ offsetof(Parse,nVar)  /* Recursive part */
#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ)  /* Pointer to tail */

/*
** Return true if currently inside an sqlite3_declare_vtab() call.
*/
#ifdef SQLITE_OMIT_VIRTUALTABLE
  #define IN_DECLARE_VTAB 0
#else
  #define IN_DECLARE_VTAB (pParse->declareVtab)
................................................................................
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
................................................................................
** Bit 0x20 is set if the mapped character requires translation to upper
** case. i.e. if the character is a lower-case ASCII character.
** If x is a lower-case ASCII character, then its upper-case equivalent
** is (x - 0x20). Therefore toupper() can be implemented as:
**
**   (x & ~(map[x]&0x20))
**
** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
** array. tolower() is used more often than toupper() by SQLite.
**
** Bit 0x40 is set if the character is non-alphanumeric and can be used in an 
** SQLite identifier.  Identifiers are alphanumerics, "_", "$", and any
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.



*/
#ifdef SQLITE_ASCII
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
................................................................................
** page size in bytes.
*/
#ifndef SQLITE_SORTER_PMASZ
# define SQLITE_SORTER_PMASZ 250
#endif

/* Statement journals spill to disk when their size exceeds the following
** threshold (in bytes). 0 means that statement journals are created and
** written to disk immediately (the default behavior for SQLite versions
** before 3.12.0).  -1 means always keep the entire statement journal in
** memory.  (The statement journal is also always held entirely in memory
** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
** setting.)
*/
#ifndef SQLITE_STMTJRNL_SPILL 
................................................................................
};


/*
** The value of the "pending" byte must be 0x40000000 (1 byte past the
** 1-gibabyte boundary) in a compatible database.  SQLite never uses
** the database page that contains the pending byte.  It never attempts
** to read or write that page.  The pending byte page is set aside
** for use by the VFS layers as space for managing file locks.
**
** During testing, it is often desirable to move the pending byte to
** 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.
................................................................................
** Boolean values
*/
typedef unsigned Bool;

/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;




/* Elements of the linked list at Vdbe.pAuxData */
typedef struct AuxData AuxData;

/* Types of VDBE cursors */
#define CURTYPE_BTREE       0
#define CURTYPE_SORTER      1
#define CURTYPE_VTAB        2
................................................................................
  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[] */
};


/*
** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
*/
#define CACHE_STALE 0

/*
** When a sub-program is executed (OP_Program), a structure of this type
** is allocated to store the current value of the program counter, as
** well as the current memory cell array and various other frame specific
** values stored in the Vdbe struct. When the sub-program is finished, 
** these values are copied back to the Vdbe from the VdbeFrame structure,
** restoring the state of the VM to as it was before the sub-program
................................................................................
  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))])






/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
*/
struct Mem {
  union MemValue {
................................................................................
  int isError;            /* Error code returned by the function. */
  u8 skipFlag;            /* Skip accumulator loading if true */
  u8 fErrorOrAux;         /* isError!=0 or pVdbe->pAuxData modified */
  u8 argc;                /* Number of arguments */
  sqlite3_value *argv[1]; /* Argument set */
};













/* 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 {
................................................................................
** 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.
*/
struct Vdbe {
  sqlite3 *db;            /* The database connection that owns this statement */
  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
  Parse *pParse;          /* Parsing context used to create this Vdbe */
  ynVar nVar;             /* Number of entries in aVar[] */
  ynVar nzVar;            /* Number of entries in azVar[] */
  u32 magic;              /* Magic number for sanity checking */
  int nMem;               /* Number of memory locations currently allocated */
  int nCursor;            /* Number of slots in apCsr[] */
  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  int nChange;            /* Number of db changes made since last reset */
  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
  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 */

  /* When allocating a new Vdbe object, all of the fields below should be
  ** initialized to zero or NULL */

  Op *aOp;                /* Space to hold the virtual machine's program */
  Mem *aMem;              /* The memory locations */
  Mem **apArg;            /* Arguments to currently executing user function */
  Mem *aColName;          /* Column names to return */
  Mem *pResultSet;        /* Pointer to an array of results */





  char *zErrMsg;          /* Error message written here */

  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
  Mem *aVar;              /* Values for the OP_Variable opcode. */
  char **azVar;           /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#endif
  int nOp;                /* Number of instructions in the program */

#ifdef SQLITE_DEBUG
  int rcApp;              /* errcode set by sqlite3_result_error_code() */
#endif
  u16 nResColumn;         /* Number of columns in one row of the result set */
  u8 errorAction;         /* Recovery action to do in case of an error */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  bft expired:1;          /* True if the VM needs to be recompiled */
  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */

  bft explain:2;          /* True if EXPLAIN present on SQL command */
  bft changeCntOn:1;      /* True to update the change-counter */
  bft runOnlyOnce:1;      /* Automatically expire on reset */
  bft usesStmtJournal:1;  /* True if uses a statement journal */
  bft readOnly:1;         /* True for statements that do not write */
  bft bIsReader:1;        /* True for statements that read */
  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */

  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */

  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */







  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 */
................................................................................
  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
#endif
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x16bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0x2df20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x319c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_RESET    0x48fa9f76    /* Reset and ready to run again */
#define VDBE_MAGIC_DEAD     0x5606c3c8    /* The VDBE has been deallocated */

/*
** Structure used to store the context required by the 
** sqlite3_preupdate_*() API functions.
*/
struct PreUpdate {
  Vdbe *v;
................................................................................
/*
** The hashing function.
*/
static unsigned int strHash(const char *z){
  unsigned int h = 0;
  unsigned char c;
  while( (c = (unsigned char)*z++)!=0 ){     /*OPTIMIZATION-IF-TRUE*/
    /* Knuth multiplicative hashing.  (Sorting & Searching, p. 510).
    ** 0x9e3779b1 is 2654435761 which is the closest prime number to
    ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
    h += sqlite3UpperToLower[c];
    h *= 0x9e3779b1;
  }
  return h;
}


/* Link pNew element into the hash table pH.  If pEntry!=0 then also
** insert pNew into the pEntry hash bucket.
................................................................................
  Pgno pgno,                  /* Page number obtained */
  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
){
  PgHdr *pPgHdr;
  assert( pPage!=0 );
  pPgHdr = (PgHdr*)pPage->pExtra;
  assert( pPgHdr->pPage==0 );
  memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
  pPgHdr->pPage = pPage;
  pPgHdr->pData = pPage->pBuf;
  pPgHdr->pExtra = (void *)&pPgHdr[1];
  memset(pPgHdr->pExtra, 0, pCache->szExtra);
  pPgHdr->pCache = pCache;
  pPgHdr->pgno = pgno;
  pPgHdr->flags = PGHDR_CLEAN;
................................................................................
  const void *pKey,   /* Packed key if the btree is an index */
  i64 nKey,           /* Integer key for tables.  Size of pKey for indices */
  int bias,           /* Bias search to the high end */
  int *pRes           /* Write search results here */
){
  int rc;                    /* Status code */
  UnpackedRecord *pIdxKey;   /* Unpacked index key */
  char aSpace[384];          /* Temp space for pIdxKey - to avoid a malloc */
  char *pFree = 0;

  if( pKey ){
    assert( nKey==(i64)(int)nKey );
    pIdxKey = sqlite3VdbeAllocUnpackedRecord(
        pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
    );
................................................................................
    nPayload = pX->nData + pX->nZero;
    pSrc = pX->pData;
    nSrc = pX->nData;
    assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
    nHeader += putVarint32(&pCell[nHeader], nPayload);
    nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
  }else{


    assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
    nSrc = nPayload = (int)pX->nKey;
    pSrc = pX->pKey;
    nHeader += putVarint32(&pCell[nHeader], nPayload);
  }
  
  /* Fill in the payload */
................................................................................
** function. If an error occurs while doing so, return 0 and write an 
** error message to pErrorDb.
*/
static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
  int i = sqlite3FindDbName(pDb, zDb);

  if( i==1 ){
    Parse sParse;
    int rc = 0;
    memset(&sParse, 0, sizeof(sParse));




    sParse.db = pDb;
    if( sqlite3OpenTempDatabase(&sParse) ){
      sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
      rc = SQLITE_ERROR;
    }
    sqlite3DbFree(pErrorDb, sParse.zErrMsg);
    sqlite3ParserReset(&sParse);


    if( rc ){
      return 0;
    }
  }

  if( i<0 ){
    sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
................................................................................
  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );
  assert( (pMem->flags&MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );


  if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
    pMem->enc = 0;
    return SQLITE_NOMEM_BKPT;
  }

  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
  ** string representation of the value. Then, if the required encoding
  ** is UTF-16le or UTF-16be do a translation.
  ** 
................................................................................
SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
  if( pMem->flags & MEM_Null ) return;
  switch( aff ){
    case SQLITE_AFF_BLOB: {   /* Really a cast to BLOB */
      if( (pMem->flags & MEM_Blob)==0 ){
        sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
        assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
        if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
      }else{
        pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
      }
      break;
    }
    case SQLITE_AFF_NUMERIC: {
      sqlite3VdbeMemNumerify(pMem);
................................................................................
  int op;
  char *zVal = 0;
  sqlite3_value *pVal = 0;
  int negInt = 1;
  const char *zNeg = "";
  int rc = SQLITE_OK;

  assert( pExpr!=0 );



  while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
  if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;

  /* Compressed expressions only appear when parsing the DEFAULT clause
  ** on a table column definition, and hence only when pCtx==0.  This
  ** check ensures that an EP_TokenOnly expression is never passed down
  ** into valueFromFunction(). */
................................................................................
SQLITE_PRIVATE int sqlite3ValueFromExpr(
  sqlite3 *db,              /* The database connection */
  Expr *pExpr,              /* The expression to evaluate */
  u8 enc,                   /* Encoding to use */
  u8 affinity,              /* Affinity to use */
  sqlite3_value **ppVal     /* Write the new value here */
){
  return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
}

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** The implementation of the sqlite_record() function. This function accepts
** a single argument of any type. The return value is a formatted database 
** record (a blob) containing the argument value.
................................................................................

/*
** Create a new virtual database engine.
*/
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
  sqlite3 *db = pParse->db;
  Vdbe *p;
  p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
  if( p==0 ) return 0;
  memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
  p->db = db;
  if( db->pVdbe ){
    db->pVdbe->pPrev = p;
  }
  p->pNext = db->pVdbe;
  p->pPrev = 0;
  db->pVdbe = p;
................................................................................
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  pOp->zComment = 0;
#endif
#ifdef SQLITE_DEBUG
  if( p->db->flags & SQLITE_VdbeAddopTrace ){
    int jj, kk;
    Parse *pParse = p->pParse;
    for(jj=kk=0; jj<pParse->nColCache; jj++){
      struct yColCache *x = pParse->aColCache + jj;

      printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
      kk++;
    }
    if( kk ) printf("\n");
    sqlite3VdbePrintOp(0, i, &p->aOp[i]);
    test_addop_breakpoint();
  }
................................................................................
  int j = ADDR(x);
  assert( v->magic==VDBE_MAGIC_INIT );
  assert( j<p->nLabel );
  assert( j>=0 );
  if( p->aLabel ){
    p->aLabel[j] = v->nOp;
  }

}

/*
** Mark the VDBE as one that can only be run one time.
*/
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
  p->runOnlyOnce = 1;
................................................................................
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p2 = val;
}
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p3 = val;
}
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
  assert( p->nOp>0 || p->db->mallocFailed );
  if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){

  sqlite3VdbeChangeP2(p, addr, p->nOp);
}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
................................................................................
}

/*
** 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>0 && p->aOp[p->nOp-1].opcode==op ){
    return sqlite3VdbeChangeToNoop(p, p->nOp-1);
  }else{
    return 0;
  }
}

/*
................................................................................
  fprintf(pOut, zFormat1, pc, 
      sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
      zCom
  );
  fflush(pOut);
}
#endif

/*
** Initialize an array of N Mem element.
*/
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
  while( (N--)>0 ){
    p->db = db;
    p->flags = flags;
    p->szMalloc = 0;
#ifdef SQLITE_DEBUG
    p->pScopyFrom = 0;
#endif
    p++;
  }
}

/*
** Release an array of N Mem elements
*/
static void releaseMemArray(Mem *p, int N){
  if( p && N ){
    Mem *pEnd = &p[N];
................................................................................
    if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
      assert( p->db->mallocFailed );
      return SQLITE_ERROR;
    }
    pMem->flags = MEM_Str|MEM_Term;
    zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
    if( zP4!=pMem->z ){
      pMem->n = 0;
      sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
    }else{
      assert( pMem->z!=0 );
      pMem->n = sqlite3Strlen30(pMem->z);
      pMem->enc = SQLITE_UTF8;
    }
    pMem++;
................................................................................
** running it.
*/
SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
  int i;
#endif
  assert( p!=0 );
  assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );

  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
  p->magic = VDBE_MAGIC_RUN;
................................................................................
  ** of the prepared statement.
  */
  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode memory used */
  x.pSpace = &((u8*)p->aOp)[n];               /* Unused opcode memory */
  assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
  x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
  assert( x.nFree>=0 );


  assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );


  resolveP2Values(p, &nArg);
  p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
  if( pParse->explain && nMem<10 ){
    nMem = 10;
  }
  p->expired = 0;
................................................................................
    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
    if( x.nNeeded==0 ) break;
    x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
    x.nFree = x.nNeeded;
  }while( !db->mallocFailed );









  p->nzVar = pParse->nzVar;
  p->azVar = pParse->azVar;
  pParse->nzVar =  0;
  pParse->azVar = 0;
  p->explain = pParse->explain;
  if( db->mallocFailed ){
    p->nVar = 0;
    p->nCursor = 0;
    p->nMem = 0;



  }else{
    p->nCursor = nCursor;
    p->nVar = (ynVar)nVar;
    initMemArray(p->aVar, nVar, db, MEM_Null);
    p->nMem = nMem;
    initMemArray(p->aMem, nMem, db, MEM_Undefined);
    memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    memset(p->anExec, 0, p->nOp*sizeof(i64));
#endif
  }

  sqlite3VdbeRewind(p);
}

/*
** Close a VDBE cursor and release all the resources that cursor 
** happens to hold.
*/
................................................................................
  int n;
  sqlite3 *db = p->db;

  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  sqlite3DbFree(db, p->aColName);
  n = nResColumn*COLNAME_N;
  p->nResColumn = (u16)nResColumn;
  p->aColName = pColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  initMemArray(p->aColName, n, p->db, MEM_Null);




}

/*
** Set the name of the idx'th column to be returned by the SQL statement.
** zName must be a pointer to a nul terminated string.
**
** This call must be made after a call to sqlite3VdbeSetNumCols().
................................................................................
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif
  p->iCurrentTime = 0;
  p->magic = VDBE_MAGIC_RESET;
  return p->rc & db->errMask;
}
 
/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** the result code.  Write any error message text into *pzErrMsg.
*/
................................................................................
** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
** the database connection and frees the object itself.
*/
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
  SubProgram *pSub, *pNext;
  int i;
  assert( p->db==0 || p->db==db );

  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  for(pSub=p->pProgram; pSub; pSub=pNext){
    pNext = pSub->pNext;
    vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
    sqlite3DbFree(db, pSub);
  }
  if( p->magic!=VDBE_MAGIC_INIT ){
    releaseMemArray(p->aVar, p->nVar);
    for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
    sqlite3DbFree(db, p->azVar);
    sqlite3DbFree(db, p->pFree);
  }
  vdbeFreeOpArray(db, p->aOp, p->nOp);
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  for(i=0; i<p->nScan; i++){
    sqlite3DbFree(db, p->aScan[i].zName);
  }
  sqlite3DbFree(db, p->aScan);
#endif
}
................................................................................
}

/*
** Return true if the prepared statement is in need of being reset.
*/
SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
  Vdbe *v = (Vdbe*)pStmt;
  return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
}

/*
** 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.
................................................................................
case OP_Null: {           /* out2 */
  int cnt;
  u16 nullFlag;
  pOut = out2Prerelease(p, pOp);
  cnt = pOp->p3-pOp->p2;
  assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
  pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
  pOut->n = 0;
  while( cnt>0 ){
    pOut++;
    memAboutToChange(p, pOut);
    sqlite3VdbeMemSetNull(pOut);
    pOut->flags = nullFlag;
    pOut->n = 0;
    cnt--;
  }
  break;
}

/* Opcode: SoftNull P1 * * * *
** Synopsis: r[P1]=NULL
................................................................................
  rc = ExpandBlob(pIn2);
  if( rc ) goto abort_due_to_error;
  if( pOp->opcode==OP_SorterInsert ){
    rc = sqlite3VdbeSorterWrite(pC, pIn2);
  }else{
    x.nKey = pIn2->n;
    x.pKey = pIn2->z;



    rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3, 
        ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
        );
    assert( pC->deferredMoveto==0 );
    pC->cacheStatus = CACHE_STALE;
  }
  if( rc) goto abort_due_to_error;
................................................................................
      const char *zColumn;
      const char *zTable;
      const char *zDb;
      Expr *pRight;

      /* if( pSrcList==0 ) break; */
      notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);

      pRight = pExpr->pRight;
      if( pRight->op==TK_ID ){
        zDb = 0;
        zTable = pExpr->pLeft->u.zToken;
        zColumn = pRight->u.zToken;
      }else{
        assert( pRight->op==TK_DOT );
................................................................................
      int is_agg = 0;             /* True if is an aggregate function */
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      u8 enc = ENC(pParse->db);   /* The database encoding */

      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );

      zId = pExpr->u.zToken;
      nId = sqlite3Strlen30(zId);
      pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;
................................................................................
          ** constant because they are constant for the duration of one query */
          ExprSetProperty(pExpr,EP_ConstFunc);
        }
        if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
          /* Date/time functions that use 'now', and other functions like
          ** sqlite_version() that might change over time cannot be used
          ** in an index. */
          notValid(pParse, pNC, "non-deterministic functions",
                   NC_IdxExpr|NC_PartIdx);
        }
      }
      if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
        sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
        pNC->nErr++;
        is_agg = 0;
      }else if( no_such_func && pParse->db->init.busy==0
................................................................................
** Special case:  If op==TK_INTEGER and pToken points to a string that
** can be translated into a 32-bit integer, then the token is not
** stored in u.zToken.  Instead, the integer values is written
** into u.iValue and the EP_IntValue flag is set.  No extra storage
** is allocated to hold the integer text and the dequote flag is ignored.
*/
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
  sqlite3 *db,            /* Handle for sqlite3DbMallocRawNN() */
  int op,                 /* Expression opcode */
  const Token *pToken,    /* Token argument.  Might be NULL */
  int dequote             /* True to dequote */
){
  Expr *pNew;
  int nExtra = 0;
  int iValue = 0;
................................................................................
** the SQL statement comes from an external source.
**
** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
** as the previous instance of the same wildcard.  Or if this is the first
** instance of the wildcard, the next sequential variable number is
** assigned.
*/
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
  sqlite3 *db = pParse->db;
  const char *z;

  if( pExpr==0 ) return;
  assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
  z = pExpr->u.zToken;
  assert( z!=0 );
  assert( z[0]!=0 );
  assert( n==sqlite3Strlen30(z) );
  if( z[1]==0 ){
    /* Wildcard of the form "?".  Assign the next variable number */
    assert( z[0]=='?' );
    pExpr->iColumn = (ynVar)(++pParse->nVar);
  }else{
    ynVar x;

    if( z[0]=='?' ){
      /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
      ** use it as the variable number */
      i64 i;
      int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
      x = (ynVar)i;
      testcase( i==0 );
      testcase( i==1 );
      testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
      testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
      if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
        sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
            db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
        return;
      }
      if( i>pParse->nVar ){
        pParse->nVar = (int)i;
      }
    }else{
      /* Wildcards like ":aaa", "$aaa" or "@aaa".  Reuse the same variable
      ** number as the prior appearance of the same name, or if the name
      ** has never appeared before, reuse the same variable number
      */
      ynVar i;
      for(i=x=0; i<pParse->nzVar; i++){
        if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
          x = (ynVar)i+1;
          break;
        }
      }
      if( x==0 ) x = (ynVar)(++pParse->nVar);
    }
    pExpr->iColumn = x;
    if( x>pParse->nzVar ){
      char **a;
      a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
      if( a==0 ){
        assert( db->mallocFailed ); /* Error reported through mallocFailed */
        return;
      }
      pParse->azVar = a;
      memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
      pParse->nzVar = x;
    }
    if( pParse->azVar[x-1]==0 ){

      pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
    }
  } 

  if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
    sqlite3ErrorMsg(pParse, "too many SQL variables");
  }
}

/*
** Recursively delete an expression tree.
*/
................................................................................
        codeReal(v, z, negFlag, iMem);
      }
#endif
    }
  }
}


/*

** Erase column-cache entry number i
*/












static void cacheEntryClear(Parse *pParse, int i){
  if( pParse->aColCache[i].tempReg ){
    if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
      pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
    }

  }

  pParse->nColCache--;

  if( i<pParse->nColCache ){
    pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
  }
}


/*
** Record in the column cache that a particular column from a
** particular table is stored in a particular register.
*/
................................................................................

  /* First replace any existing entry.
  **
  ** Actually, the way the column cache is currently used, we are guaranteed
  ** that the object will never already be in cache.  Verify this guarantee.
  */
#ifndef NDEBUG
  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
    assert( p->iTable!=iTab || p->iColumn!=iCol );
  }
#endif

  /* If the cache is already full, delete the least recently used entry */








  if( pParse->nColCache>=SQLITE_N_COLCACHE ){






    minLru = 0x7fffffff;
    idxLru = -1;
    for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
      if( p->lru<minLru ){
        idxLru = i;
        minLru = p->lru;
      }
    }

    p = &pParse->aColCache[idxLru];
  }else{
    p = &pParse->aColCache[pParse->nColCache++];
  }

  /* Add the new entry to the end of the cache */
  p->iLevel = pParse->iCacheLevel;
  p->iTable = iTab;
  p->iColumn = iCol;
  p->iReg = iReg;
  p->tempReg = 0;
  p->lru = pParse->iCacheCnt++;



}

/*
** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
** Purge the range of registers from the column cache.
*/
SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
  int i = 0;
  while( i<pParse->nColCache ){
    struct yColCache *p = &pParse->aColCache[i];

    if( p->iReg >= iReg && p->iReg < iReg+nReg ){
      cacheEntryClear(pParse, i);
    }else{

      i++;
    }
  }
}

/*
** Remember the current column cache context.  Any new entries added
** added to the column cache after this call are removed when the
** corresponding pop occurs.
................................................................................

/*
** Remove from the column cache any entries that were added since the
** the previous sqlite3ExprCachePush operation.  In other words, restore
** the cache to the state it was in prior the most recent Push.
*/
SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
  int i = 0;

  assert( pParse->iCacheLevel>=1 );
  pParse->iCacheLevel--;
#ifdef SQLITE_DEBUG
  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
    printf("POP  to %d\n", pParse->iCacheLevel);
  }
#endif
  while( i<pParse->nColCache ){
    if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
      cacheEntryClear(pParse, i);
    }else{
      i++;
    }
  }
}

/*
** When a cached column is reused, make sure that its register is
** no longer available as a temp register.  ticket #3879:  that same
** register might be in the cache in multiple places, so be sure to
** get them all.
*/
static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
  int i;
  struct yColCache *p;
  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
    if( p->iReg==iReg ){
      p->tempReg = 0;
    }
  }
}

/* Generate code that will load into register regOut a value that is
................................................................................
  int iReg,        /* Store results here */
  u8 p5            /* P5 value for OP_Column + FLAGS */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  struct yColCache *p;

  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
    if( p->iTable==iTable && p->iColumn==iColumn ){
      p->lru = pParse->iCacheCnt++;
      sqlite3ExprCachePinRegister(pParse, p->iReg);
      return p->iReg;
    }
  }  
  assert( v!=0 );
  sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
................................................................................


/*
** Clear all column cache entries.
*/
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
  int i;


#if SQLITE_DEBUG
  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
    printf("CLEAR\n");
  }
#endif
  for(i=0; i<pParse->nColCache; i++){
    if( pParse->aColCache[i].tempReg
     && pParse->nTempReg<ArraySize(pParse->aTempReg)
    ){
       pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
    }
  }
  pParse->nColCache = 0;
}

/*
** Record the fact that an affinity change has occurred on iCount
** registers starting with iStart.
*/
SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
................................................................................
**
** This routine is used within assert() and testcase() macros only
** and does not appear in a normal build.
*/
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
  int i;
  struct yColCache *p;
  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
    int r = p->iReg;
    if( r>=iFrom && r<=iTo ) return 1;    /*NO_TEST*/
  }
  return 0;
}
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */

................................................................................
** the deallocation is deferred until the column cache line that uses
** the register becomes stale.
*/
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
  if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
    int i;
    struct yColCache *p;
    for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
      if( p->iReg==iReg ){
        p->tempReg = 1;
        return;
      }
    }
    pParse->aTempReg[pParse->nTempReg++] = iReg;
  }
................................................................................
  /* Begin by generating some termination code at the end of the
  ** vdbe program
  */
  v = sqlite3GetVdbe(pParse);
  assert( !pParse->isMultiWrite 
       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
  if( v ){

    sqlite3VdbeAddOp0(v, OP_Halt);

#if SQLITE_USER_AUTHENTICATION
    if( pParse->nTableLock>0 && db->init.busy==0 ){
      sqlite3UserAuthInit(db);
      if( db->auth.authLevel<UAUTH_User ){
        sqlite3ErrorMsg(pParse, "user not authenticated");
................................................................................
    if( db->mallocFailed==0 
     && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
    ){
      int iDb, i;
      assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
      sqlite3VdbeJumpHere(v, 0);
      for(iDb=0; iDb<db->nDb; iDb++){
        Schema *pSchema;
        if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
        sqlite3VdbeUsesBtree(v, iDb);
        pSchema = db->aDb[iDb].pSchema;
        sqlite3VdbeAddOp4Int(v,
          OP_Transaction,                    /* Opcode */
          iDb,                               /* P1 */
          DbMaskTest(pParse->writeMask,iDb), /* P2 */
          pSchema->schema_cookie,            /* P3 */
          pSchema->iGeneration               /* P4 */
        );
        if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
        VdbeComment((v,
              "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
      }
#ifndef SQLITE_OMIT_VIRTUALTABLE
      for(i=0; i<pParse->nVtabLock; i++){
................................................................................
    *  See ticket [a696379c1f08866] */
    if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
    sqlite3VdbeMakeReady(v, pParse);
    pParse->rc = SQLITE_DONE;
  }else{
    pParse->rc = SQLITE_ERROR;
  }










}

/*
** Run the parser and code generator recursively in order to generate
** code for the SQL statement given onto the end of the pParse context
** currently under construction.  When the parser is run recursively
** this way, the final OP_Halt is not appended and other initialization
................................................................................
** care if you decide to try to use this routine for some other purposes.
*/
SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  char *zErrMsg = 0;
  sqlite3 *db = pParse->db;

  char saveBuf[PARSE_TAIL_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(db, zFormat, ap);
  va_end(ap);
  if( zSql==0 ){
    return;   /* A malloc must have failed */
  }
  pParse->nested++;
  memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
  sqlite3RunParser(pParse, zSql, &zErrMsg);
  sqlite3DbFree(db, zErrMsg);
  sqlite3DbFree(db, zSql);
  memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
  pParse->nested--;
}

#if SQLITE_USER_AUTHENTICATION
/*
** Return TRUE if zTable is the name of the system table that stores the
** list of users and their access credentials.
................................................................................
** Record the fact that the schema cookie will need to be verified
** for database iDb.  The code to actually verify the schema cookie
** will occur at the end of the top-level VDBE and will be generated
** later, by sqlite3FinishCoding().
*/
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);


  assert( iDb>=0 && iDb<pParse->db->nDb );
  assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
  assert( iDb<SQLITE_MAX_ATTACHED+2 );
  assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
  if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
    DbMaskSet(pToplevel->cookieMask, iDb);

    if( !OMIT_TEMPDB && iDb==1 ){
      sqlite3OpenTempDatabase(pToplevel);
    }
  }
}

/*
................................................................................
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }
  if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
  sqlite3ReleaseTempReg(pParse, regRowid);
  sqlite3ReleaseTempReg(pParse, regData);
  if( emptyDestTest ){
    sqlite3AutoincrementEnd(pParse);
    sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
    sqlite3VdbeJumpHere(v, emptyDestTest);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
    return 0;
  }else{
    return 1;
  }
................................................................................
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
  Vdbe *pReprepare,         /* VM being reprepared */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){

  char *zErrMsg = 0;        /* Error message */
  int rc = SQLITE_OK;       /* Result code */
  int i;                    /* Loop counter */

  Parse sParse;             /* Parsing context */





  memset(&sParse, 0, PARSE_HDR_SZ);
  memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
  sParse.pReprepare = pReprepare;
  assert( ppStmt && *ppStmt==0 );
  /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
  assert( sqlite3_mutex_held(db->mutex) );

  /* Check to verify that it is possible to get a read lock on all
  ** database schemas.  The inability to get a read lock indicates that
  ** some other database connection is holding a write-lock, which in
................................................................................
        goto end_prepare;
      }
    }
  }

  sqlite3VtabUnlockList(db);

  sParse.db = db;

  if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
    char *zSqlCopy;
    int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
    testcase( nBytes==mxLen );
    testcase( nBytes==mxLen+1 );
    if( nBytes>mxLen ){
      sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long");
      rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
      goto end_prepare;
    }
    zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
    if( zSqlCopy ){
      sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
      sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
      sqlite3DbFree(db, zSqlCopy);
    }else{
      sParse.zTail = &zSql[nBytes];
    }
  }else{
    sqlite3RunParser(&sParse, zSql, &zErrMsg);
  }
  assert( 0==sParse.nQueryLoop );

  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.checkSchema ){
    schemaIsValid(&sParse);
  }
  if( db->mallocFailed ){
    sParse.rc = SQLITE_NOMEM_BKPT;
  }
  if( pzTail ){
    *pzTail = sParse.zTail;
  }
  rc = sParse.rc;

#ifndef SQLITE_OMIT_EXPLAIN
  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
    static const char * const azColName[] = {
       "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
       "selectid", "order", "from", "detail"
    };
    int iFirst, mx;
    if( sParse.explain==2 ){
      sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
      iFirst = 8;
      mx = 12;
    }else{
      sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
      iFirst = 0;
      mx = 8;
    }
    for(i=iFirst; i<mx; i++){
      sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
                            azColName[i], SQLITE_STATIC);
    }
  }
#endif

  if( db->init.busy==0 ){
    Vdbe *pVdbe = sParse.pVdbe;
    sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
  }
  if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
    sqlite3VdbeFinalize(sParse.pVdbe);
    assert(!(*ppStmt));
  }else{
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }

  if( zErrMsg ){
    sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
    sqlite3DbFree(db, zErrMsg);
  }else{
    sqlite3Error(db, rc);
  }

  /* Delete any TriggerPrg structures allocated while parsing this statement. */
  while( sParse.pTriggerPrg ){
    TriggerPrg *pT = sParse.pTriggerPrg;
    sParse.pTriggerPrg = pT->pNext;
    sqlite3DbFree(db, pT);
  }

end_prepare:

  sqlite3ParserReset(&sParse);

  rc = sqlite3ApiExit(db, rc);
  assert( (rc&db->errMask)==rc );
  return rc;
}
static int sqlite3LockAndPrepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
................................................................................

/*
** Allocate a KeyInfo object sufficient for an index of N key columns and
** X extra columns.
*/
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
  int nExtra = (N+X)*(sizeof(CollSeq*)+1);
  KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
  if( p ){
    p->aSortOrder = (u8*)&p->aColl[N+X];
    p->nField = (u16)N;
    p->nXField = (u16)X;
    p->enc = ENC(db);
    p->db = db;
    p->nRef = 1;
................................................................................
**
** The number of terms in a join is limited by the number of bits
** in prereqRight and prereqAll.  The default is 64 bits, hence SQLite
** is only able to process joins with 64 or fewer tables.
*/
struct WhereTerm {
  Expr *pExpr;            /* Pointer to the subexpression that is this term */
  WhereClause *pWC;       /* The clause this term is part of */
  LogEst truthProb;       /* Probability of truth for this expression */
  u16 wtFlags;            /* TERM_xxx bit flags.  See below */
  u16 eOperator;          /* A WO_xx value describing <op> */
  u8 nChild;              /* Number of children that must disable us */
  u8 eMatchOp;            /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
  int iParent;            /* Disable pWC->a[iParent] when this term disabled */
  int leftCursor;         /* Cursor number of X in "X <op> <expr>" */
  int iField;             /* Field in (?,?,?) IN (SELECT...) vector */
  union {
    int leftColumn;         /* Column number of X in "X <op> <expr>" */
    WhereOrInfo *pOrInfo;   /* Extra information if (eOperator & WO_OR)!=0 */
    WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
  } u;






  Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */
};

/*
** Allowed values of WhereTerm.wtFlags
*/
................................................................................
** planner.
*/
struct WhereInfo {
  Parse *pParse;            /* Parsing and code generating context */
  SrcList *pTabList;        /* List of tables in the join */
  ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
  ExprList *pDistinctSet;   /* DISTINCT over all these values */



  LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
  int aiCurOnePass[2];      /* OP_OpenWrite cursors for the ONEPASS opt */
  int iContinue;            /* Jump here to continue with next record */
  int iBreak;               /* Jump here to break out of the loop */
  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
  u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
  u8 nLevel;                /* Number of nested loop */
  i8 nOBSat;                /* Number of ORDER BY terms satisfied by indices */
  u8 sorted;                /* True if really sorted (not just grouped) */
  u8 eOnePass;              /* ONEPASS_OFF, or _SINGLE, or _MULTI */
  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values */

  u8 bOrderedInnerLoop;     /* True if only the inner-most loop is ordered */
  int iTop;                 /* The very beginning of the WHERE loop */
  WhereLoop *pLoops;        /* List of all WhereLoop objects */
  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
  LogEst nRowOut;           /* Estimated number of output rows */
  WhereClause sWC;          /* Decomposition of the WHERE clause */

  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */

  WhereLevel a[1];          /* Information about each nest loop in WHERE */
};

/*
** Private interfaces - callable only by other where.c routines.
**
** where.c:
................................................................................
** to the pRight values. This function modifies characters within the
** affinity string to SQLITE_AFF_BLOB if either:
**
**   * the comparison will be performed with no affinity, or
**   * the affinity change in zAff is guaranteed not to change the value.
*/
static void updateRangeAffinityStr(

  Expr *pRight,                   /* RHS of comparison */
  int n,                          /* Number of vector elements in comparison */
  char *zAff                      /* Affinity string to modify */
){
  int i;
  for(i=0; i<n; i++){
    Expr *p = sqlite3VectorFieldSubexpr(pRight, i);
................................................................................
        testcase( bRev );
        testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
        assert( (bRev & ~1)==0 );
        pLevel->iLikeRepCntr <<=1;
        pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
      }
#endif
      if( pRangeStart==0 ){
        j = pIdx->aiColumn[nEq];
        if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){

          bSeekPastNull = 1;
        }
      }
    }
    assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );

    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).
................................................................................
      if( (pRangeStart->wtFlags & TERM_VNULL)==0
       && sqlite3ExprCanBeNull(pRight)
      ){
        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
        VdbeCoverage(v);
      }
      if( zStartAff ){
        updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]);
      }  
      nConstraint += nBtm;
      testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
      if( sqlite3ExprIsVector(pRight)==0 ){
        disableTerm(pLevel, pRangeStart);
      }else{
        startEq = 1;
................................................................................
      if( (pRangeEnd->wtFlags & TERM_VNULL)==0
       && sqlite3ExprCanBeNull(pRight)
      ){
        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
        VdbeCoverage(v);
      }
      if( zEndAff ){
        updateRangeAffinityStr(pRight, nTop, zEndAff);
        codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
      }else{
        assert( pParse->db->mallocFailed );
      }
      nConstraint += nTop;
      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );

................................................................................
  **
  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
  ** and we are coding the t1 loop and the t2 loop has not yet coded,
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
  ** the implied "t1.a=123" constraint.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE, sEAlt;
    WhereTerm *pAlt;
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
    if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
................................................................................
                    WO_EQ|WO_IN|WO_IS, 0);
    if( pAlt==0 ) continue;
    if( pAlt->wtFlags & (TERM_CODED) ) continue;
    testcase( pAlt->eOperator & WO_EQ );
    testcase( pAlt->eOperator & WO_IS );
    testcase( pAlt->eOperator & WO_IN );
    VdbeModuleComment((v, "begin transitive constraint"));


    sEAlt = *pAlt->pExpr;
    sEAlt.pLeft = pE->pLeft;
    sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);


  }

  /* For a LEFT OUTER JOIN, generate code that will record the fact that
  ** at least one row of the right table has matched the left table.  
  */
  if( pLevel->iLeftJoin ){
    pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
................................................................................
      return 0;
    }
    memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
    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;
  memset(&pTerm->eOperator, 0,
         sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
  return idx;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL"
................................................................................
** and the index:
**
**   CREATE INDEX ... ON (a, b, c, d, e)
**
** then this function would be invoked with nEq=1. The value returned in
** this case is 3.
*/
static int whereRangeVectorLen(
  Parse *pParse,       /* Parsing context */
  int iCur,            /* Cursor open on pIdx */
  Index *pIdx,         /* The index to be used for a inequality constraint */
  int nEq,             /* Number of prior equality constraints on same index */
  WhereTerm *pTerm     /* The vector inequality constraint */
){
  int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft);
................................................................................
          }else{
            rev = revIdx ^ pOrderBy->a[i].sortOrder;
            if( rev ) *pRevMask |= MASKBIT(iLoop);
            revSet = 1;
          }
        }
        if( isMatch ){
          if( iColumn==XN_ROWID ){
            testcase( distinctColumns==0 );
            distinctColumns = 1;
          }
          obSat |= MASKBIT(i);
        }else{
          /* No match found */
          if( j==0 || j<nKeyCol ){
................................................................................
      if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
        pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
      }
    }else{
      pWInfo->nOBSat = pFrom->isOrdered;
      pWInfo->revMask = pFrom->revLoop;
      if( pWInfo->nOBSat<=0 ){
        u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
        pWInfo->nOBSat = 0;
        if( nLoop>0 && (wsFlags & WHERE_ONEROW)==0 
         && (wsFlags & (WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN)
        ){
          Bitmask m = 0;
          int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
                      WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
          testcase( wsFlags & WHERE_IPK );
          testcase( wsFlags & WHERE_COLUMN_IN );
          if( rc==pWInfo->pOrderBy->nExpr ){
            pWInfo->bOrderedInnerLoop = 1;
            pWInfo->revMask = m;
          }
        }
      }
    }
................................................................................
  ** return value. A single allocation is used to store the WhereInfo
  ** struct, the contents of WhereInfo.a[], the WhereClause structure
  ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
  ** field (type Bitmask) it must be aligned on an 8-byte boundary on
  ** some architectures. Hence the ROUND8() below.
  */
  nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
  pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
  if( db->mallocFailed ){
    sqlite3DbFree(db, pWInfo);
    pWInfo = 0;
    goto whereBeginError;
  }


  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->pOrderBy = pOrderBy;
  pWInfo->pDistinctSet = pDistinctSet;
  pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
  pWInfo->nLevel = nTabList;
  pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
  pWInfo->wctrlFlags = wctrlFlags;
  pWInfo->iLimit = iAuxArg;
  pWInfo->savedNQueryLoop = pParse->nQueryLoop;
  memset(&pWInfo->nOBSat, 0, 
         offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
  memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
  assert( pWInfo->eOnePass==ONEPASS_OFF );  /* ONEPASS defaults to OFF */
  pMaskSet = &pWInfo->sMaskSet;
  sWLB.pWInfo = pWInfo;
  sWLB.pWC = &pWInfo->sWC;
  sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
  assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
  whereLoopInit(sWLB.pNew);
................................................................................
  if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf;
}
  yymsp[0].minor.yy190 = yylhsminor.yy190;
        break;
      case 159: /* expr ::= VARIABLE */
{
  if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
    u32 n = yymsp[0].minor.yy0.n;
    spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n);
  }else{
    /* When doing a nested parse, one can include terms in an expression
    ** that look like this:   #1 #2 ...  These terms refer to registers
    ** in the virtual machine.  #N is the N-th register. */
    Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
    assert( t.n>=2 );
    spanSet(&yymsp[0].minor.yy190, &t, &t);
................................................................................
          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
             yyTracePrompt,yyTokenName[yymajor]);
        }
#endif
        yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
        yymajor = YYNOCODE;
      }else{
        while( yypParser->yytos >= yypParser->yystack
            && yymx != YYERRORSYMBOL
            && (yyact = yy_find_reduce_action(
                        yypParser->yytos->stateno,
                        YYERRORSYMBOL)) >= YY_MIN_REDUCE
        ){
          yy_pop_parser_stack(yypParser);
        }
................................................................................
static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
  const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
  char *zSql;
  sqlite3_stmt *p;
  int rc;
  i64 nRow = 0;

  rc = sqlite3_table_column_metadata(
      db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
  );
  if( rc!=SQLITE_OK ){
    pRtree->nRowEst = RTREE_DEFAULT_ROWEST;

    return rc==SQLITE_ERROR ? SQLITE_OK : rc;
  }
  zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
  if( zSql==0 ){
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
    if( rc==SQLITE_OK ){
................................................................................
          fprintf(fts5yyTraceFILE,"%sDiscard input token %s\n",
             fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
        }
#endif
        fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
        fts5yymajor = fts5YYNOCODE;
      }else{
        while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
            && fts5yymx != fts5YYERRORSYMBOL
            && (fts5yyact = fts5yy_find_reduce_action(
                        fts5yypParser->fts5yytos->stateno,
                        fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
        ){
          fts5yy_pop_parser_stack(fts5yypParser);
        }
................................................................................
  int tflags,                     /* Mask of FTS5_TOKEN_* flags */
  const char *pToken,             /* Buffer containing token */
  int nToken,                     /* Size of token in bytes */
  int iStartOff,                  /* Start offset of token */
  int iEndOff                     /* End offset of token */
){
  int rc = SQLITE_OK;

  UNUSED_PARAM2(pToken, nToken);
  UNUSED_PARAM(iEndOff);

  if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
    Fts5SFinder *p = (Fts5SFinder*)pContext;
    if( p->iPos>0 ){
      int i;
      char c = 0;
      for(i=iStartOff-1; i>=0; i--){
................................................................................

        if( rc==SQLITE_OK && sFinder.nFirst && nDocsize>nToken ){
          for(jj=0; jj<(sFinder.nFirst-1); jj++){
            if( sFinder.aFirst[jj+1]>io ) break;
          }

          if( sFinder.aFirst[jj]<io ){

            memset(aSeen, 0, nPhrase);
            rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i, 
              sFinder.aFirst[jj], nToken, &nScore, 0
            );

            nScore += (sFinder.aFirst[jj]==0 ? 120 : 100);
            if( rc==SQLITE_OK && nScore>nBestScore ){
................................................................................
static void fts5SourceIdFunc(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "fts5: 2016-10-10 14:48:36 6624c4964b63e259d5ee006eaa7ec79ddadbd6a6", -1, SQLITE_TRANSIENT);
}

static int fts5Init(sqlite3 *db){
  static const sqlite3_module fts5Mod = {
    /* iVersion      */ 2,
    /* xCreate       */ fts5CreateMethod,
    /* xConnect      */ fts5ConnectMethod,

Changes to src/sqlite3.h.

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.15.0"
#define SQLITE_VERSION_NUMBER 3015000
#define SQLITE_SOURCE_ID      "2016-09-28 16:05:53 40c0fb0af678797c39a99853f9f4102464c16f4b"

/*
** 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







|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.15.0"
#define SQLITE_VERSION_NUMBER 3015000
#define SQLITE_SOURCE_ID      "2016-10-12 15:15:30 61f0526978af667781c57bcc87510e4524efd0d8"

/*
** 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

Changes to src/stash.c.

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
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

/*
** SQL code to implement the tables needed by the stash.
*/
static const char zStashInit[] =
@ CREATE TABLE IF NOT EXISTS localdb.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 localdb.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
................................................................................
  }else{
    stash_add_file_or_dir(stashid, vid, g.zLocalRoot);
  }
  return stashid;
}

/*
** Apply a stash to the current check-out.
*/
static void stash_apply(int stashid, int nConflict){
  int vid;
  Stmt q;
  db_prepare(&q,
     "SELECT rid, isRemoved, isExec, isLink, origname, newname, delta"
     "  FROM stashfile WHERE stashid=%d",
................................................................................
**  fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
**
**     Save the current changes in the working tree as a new stash.
**     Then revert the changes back to the last check-in.  If FILES
**     are listed, then only stash and revert the named files.  The
**     "save" verb can be omitted if and only if there are no other
**     arguments.  The "snapshot" verb works the same as "save" but
**     omits the revert, keeping the check-out unchanged.
**
**  fossil stash list ?-v|--verbose?
**  fossil stash ls ?-v|--verbose?
**
**     List all changes sets currently stashed.  Show information about
**     individual files in each changeset if -v or --verbose is used.
**
**  fossil stash show|cat ?STASHID? ?DIFF-FLAGS?
**
**     Show the content of a stash
**
**  fossil stash pop
**  fossil stash apply ?STASHID?
**
**     Apply STASHID or the most recently create stash to the current
**     working check-out.  The "pop" command deletes that changeset from
**     the stash after applying it but the "apply" command retains the
**     changeset.
**
**  fossil stash goto ?STASHID?
**
**     Update to the baseline checkout for STASHID then apply the
**     changes of STASHID.  Keep STASHID so that it can be reused
**     This command is undoable.
**
**  fossil stash drop ?STASHID? ?-a|--all?
**  fossil stash rm   ?STASHID? ?-a|--all?
**
**     Forget everything about STASHID.  Forget the whole stash if the
**     -a|--all flag is used.  Individual drops are undoable but -a|--all
**     is not.
**
**  fossil stash diff ?STASHID?
**  fossil stash gdiff ?STASHID?
**
**     Show diffs of the current working directory and what that
**     directory would be if STASHID were applied.
**
** SUMMARY:
**  fossil stash
**  fossil stash save ?-m|--comment COMMENT? ?FILES...?
**  fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
**  fossil stash list|ls  ?-v|--verbose? ?-W|--width <num>?
**  fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
**  fossil stash pop
**  fossil stash apply ?STASHID?
**  fossil stash goto ?STASHID?
**  fossil stash rm|drop ?STASHID? ?-a|--all?
**  fossil stash [g]diff ?STASHID? ?DIFF-OPTIONS?
*/
void stash_cmd(void){
  const char *zCmd;
  int nCmd;
  int stashid = 0;
  undo_capture_command_line();
  db_must_be_within_tree();







|







 







|







 







|

|
<






|





|









|
<





|
|








|


|
|
|
|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
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

/*
** SQL code to implement the tables needed by the stash.
*/
static const char zStashInit[] =
@ CREATE TABLE IF NOT EXISTS localdb.stash(
@   stashid INTEGER PRIMARY KEY,     -- Unique stash identifier
@   vid INTEGER,                     -- The baseline checkout for this stash
@   comment TEXT,                    -- Comment for this stash.  Or NULL
@   ctime TIMESTAMP                  -- When the stash was created
@ );
@ CREATE TABLE IF NOT EXISTS localdb.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
................................................................................
  }else{
    stash_add_file_or_dir(stashid, vid, g.zLocalRoot);
  }
  return stashid;
}

/*
** Apply a stash to the current checkout.
*/
static void stash_apply(int stashid, int nConflict){
  int vid;
  Stmt q;
  db_prepare(&q,
     "SELECT rid, isRemoved, isExec, isLink, origname, newname, delta"
     "  FROM stashfile WHERE stashid=%d",
................................................................................
**  fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
**
**     Save the current changes in the working tree as a new stash.
**     Then revert the changes back to the last check-in.  If FILES
**     are listed, then only stash and revert the named files.  The
**     "save" verb can be omitted if and only if there are no other
**     arguments.  The "snapshot" verb works the same as "save" but
**     omits the revert, keeping the checkout unchanged.
**
**  fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?

**
**     List all changes sets currently stashed.  Show information about
**     individual files in each changeset if -v or --verbose is used.
**
**  fossil stash show|cat ?STASHID? ?DIFF-FLAGS?
**
**     Show the contents of a stash.
**
**  fossil stash pop
**  fossil stash apply ?STASHID?
**
**     Apply STASHID or the most recently create stash to the current
**     working checkout.  The "pop" command deletes that changeset from
**     the stash after applying it but the "apply" command retains the
**     changeset.
**
**  fossil stash goto ?STASHID?
**
**     Update to the baseline checkout for STASHID then apply the
**     changes of STASHID.  Keep STASHID so that it can be reused
**     This command is undoable.
**
**  fossil stash drop|rm ?STASHID? ?-a|--all?

**
**     Forget everything about STASHID.  Forget the whole stash if the
**     -a|--all flag is used.  Individual drops are undoable but -a|--all
**     is not.
**
**  fossil stash diff ?STASHID? ?DIFF-OPTIONS?
**  fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
**
**     Show diffs of the current working directory and what that
**     directory would be if STASHID were applied.
**
** SUMMARY:
**  fossil stash
**  fossil stash save ?-m|--comment COMMENT? ?FILES...?
**  fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
**  fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
**  fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
**  fossil stash pop
**  fossil stash apply|goto ?STASHID?
**  fossil stash drop|rm ?STASHID? ?-a|--all?
**  fossil stash diff ?STASHID? ?DIFF-OPTIONS?
**  fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
*/
void stash_cmd(void){
  const char *zCmd;
  int nCmd;
  int stashid = 0;
  undo_capture_command_line();
  db_must_be_within_tree();

Changes to src/tag.c.

357
358
359
360
361
362
363

364
365
366
367
368
369
370
    fossil_print("%s", blob_str(&ctrl));
    blob_reset(&ctrl);
  }else{
    nrid = content_put(&ctrl);
    manifest_crosslink(nrid, &ctrl, MC_PERMIT_HOOKS);
  }
  assert( blob_is_reset(&ctrl) );

}

/*
** COMMAND: tag
**
** Usage: %fossil tag SUBCOMMAND ...
**







>







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    fossil_print("%s", blob_str(&ctrl));
    blob_reset(&ctrl);
  }else{
    nrid = content_put(&ctrl);
    manifest_crosslink(nrid, &ctrl, MC_PERMIT_HOOKS);
  }
  assert( blob_is_reset(&ctrl) );
  manifest_to_disk(rid);
}

/*
** COMMAND: tag
**
** Usage: %fossil tag SUBCOMMAND ...
**

Changes to src/tar.c.

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
...
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
  Glob *pExclude       /* Exclude files matching this pattern */
){
  Blob mfile, hash, file;
  Manifest *pManifest;
  ManifestFile *pFile;
  Blob filename;
  int nPrefix;
  char *zName;
  unsigned int mTime;

  content_get(rid, &mfile);
  if( blob_size(&mfile)==0 ){
    blob_zero(pTar);
    return;
  }
................................................................................
  if( zDir && zDir[0] ){
    blob_appendf(&filename, "%s/", zDir);
  }
  nPrefix = blob_size(&filename);

  pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
  if( pManifest ){

    mTime = (pManifest->rDate - 2440587.5)*86400.0;
    tar_begin(mTime);



    if( (pInclude==0 || glob_match(pInclude, "manifest"))
     && !glob_match(pExclude, "manifest")
     && db_get_boolean("manifest", 0)
    ){
















      blob_append(&filename, "manifest", -1);
      zName = blob_str(&filename);


      sha1sum_blob(&mfile, &hash);


      sterilize_manifest(&mfile);
      tar_add_file(zName, &mfile, 0, mTime);


      blob_reset(&mfile);

      blob_append(&hash, "\n", 1);
      blob_resize(&filename, nPrefix);
      blob_append(&filename, "manifest.uuid", -1);
      zName = blob_str(&filename);
      tar_add_file(zName, &hash, 0, mTime);
      blob_reset(&hash);











    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;
      fid = uuid_to_rid(pFile->zUuid, 0);







|







 







>


>
>
>
|
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
|
>
>
|
|
>
>

>
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
...
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
  Glob *pExclude       /* Exclude files matching this pattern */
){
  Blob mfile, hash, file;
  Manifest *pManifest;
  ManifestFile *pFile;
  Blob filename;
  int nPrefix;
  char *zName = 0;
  unsigned int mTime;

  content_get(rid, &mfile);
  if( blob_size(&mfile)==0 ){
    blob_zero(pTar);
    return;
  }
................................................................................
  if( zDir && zDir[0] ){
    blob_appendf(&filename, "%s/", zDir);
  }
  nPrefix = blob_size(&filename);

  pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
  if( pManifest ){
    int flg, eflg = 0;
    mTime = (pManifest->rDate - 2440587.5)*86400.0;
    tar_begin(mTime);
    flg = db_get_manifest_setting();
    if( flg ){
      /* eflg is the effective flags, taking include/exclude into account */
      if( (pInclude==0 || glob_match(pInclude, "manifest"))
       && !glob_match(pExclude, "manifest")


       && (flg & MFESTFLG_RAW) ){
        eflg |= MFESTFLG_RAW;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.uuid"))
       && !glob_match(pExclude, "manifest.uuid")
       && (flg & MFESTFLG_UUID) ){
        eflg |= MFESTFLG_UUID;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
       && !glob_match(pExclude, "manifest.tags")
       && (flg & MFESTFLG_TAGS) ){
        eflg |= MFESTFLG_TAGS;
      }

      if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
        if( eflg & MFESTFLG_RAW ){
          blob_append(&filename, "manifest", -1);
          zName = blob_str(&filename);
        }
        if( eflg & MFESTFLG_UUID ){
          sha1sum_blob(&mfile, &hash);
        }
        if( eflg & MFESTFLG_RAW ) {
          sterilize_manifest(&mfile);
          tar_add_file(zName, &mfile, 0, mTime);
        }
      }
      blob_reset(&mfile);
      if( eflg & MFESTFLG_UUID ){
        blob_append(&hash, "\n", 1);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.uuid", -1);
        zName = blob_str(&filename);
        tar_add_file(zName, &hash, 0, mTime);
        blob_reset(&hash);
      }
      if( eflg & MFESTFLG_TAGS ){
        Blob tagslist;
        blob_zero(&tagslist);
        get_checkin_taglist(rid, &tagslist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.tags", -1);
        zName = blob_str(&filename);
        tar_add_file(zName, &tagslist, 0, mTime);
        blob_reset(&tagslist);
      }
    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;
      fid = uuid_to_rid(pFile->zUuid, 0);

Changes to src/timeline.c.

24
25
26
27
28
29
30









31
32
33
34
35
36
37
....
2027
2028
2029
2030
2031
2032
2033







2034
2035
2036
2037
2038
2039
2040
....
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
....
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
....
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183


2184
2185
2186
2187
2188
2189
2190
....
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
#include "timeline.h"

/*
** The value of one second in julianday notation
*/
#define ONE_SECOND (1.0/86400.0)










/*
** Add an appropriate tag to the output if "rid" is unpublished (private)
*/
#define UNPUB_TAG "<em>(unpublished)</em>"
void tag_private_status(int rid){
  if( content_is_private(rid) ){
    cgi_printf("%s", UNPUB_TAG);
................................................................................
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
................................................................................
  const char *zOffset;
  const char *zType;
  char *zOrigin;
  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){
................................................................................

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

  if( g.argc>=4 ){
    k = strlen(g.argv[2]);
    if( strncmp(g.argv[2],"before",k)==0 ){
      mode = 1;
    }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
      mode = 2;
    }else if( strncmp(g.argv[2],"descendants",k)==0 ){
      mode = 3;
    }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{
................................................................................
  }else{
    zOrigin = "now";
  }
  k = strlen(zOrigin);
  blob_zero(&uuid);
  blob_append(&uuid, zOrigin, -1);
  if( fossil_strcmp(zOrigin, "now")==0 ){
    if( mode==3 || mode==4 ){
      fossil_fatal("cannot compute descendants or ancestors of a date");
    }
    zDate = mprintf("(SELECT datetime('now'))");
  }else if( strncmp(zOrigin, "current", k)==0 ){
    if( !g.localOpen ){
      fossil_fatal("must be within a local checkout to use 'current'");
    }
    objid = db_lget_int("checkout",0);
    zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid);
  }else if( name_to_uuid(&uuid, 0, "*")==0 ){
    objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
    zDate = mprintf("(SELECT mtime FROM event WHERE objid=%d)", objid);
  }else{
    const char *zShift = "";
    if( mode==3 || mode==4 ){
      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, fromLocal()))", zOrigin, zShift);


  }

  if( zFilePattern ){
    if( zType==0 ){
      /* When zFilePattern is specified and type is not specified, only show
       * file check-ins */
      zType="ci";
................................................................................
    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, "\n  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') ){







>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>







 







|







 







|

|

|

|

|

|







 







|












|

|


|



>
>







 







|



|
|


|

|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
....
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
....
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
....
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
....
2171
2172
2173
2174
2175
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
2204
2205
2206
2207
2208
....
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
#include "timeline.h"

/*
** The value of one second in julianday notation
*/
#define ONE_SECOND (1.0/86400.0)

/*
** timeline mode options
*/
#define TIMELINE_MODE_NONE      0
#define TIMELINE_MODE_BEFORE    1
#define TIMELINE_MODE_AFTER     2
#define TIMELINE_MODE_CHILDREN  3
#define TIMELINE_MODE_PARENTS   4

/*
** Add an appropriate tag to the output if "rid" is unpublished (private)
*/
#define UNPUB_TAG "<em>(unpublished)</em>"
void tag_private_status(int rid){
  if( content_is_private(rid) ){
    cgi_printf("%s", UNPUB_TAG);
................................................................................
static int isIsoDate(const char *z){
  return strlen(z)==10
      && z[4]=='-'
      && z[7]=='-'
      && fossil_isdigit(z[0])
      && fossil_isdigit(z[5]);
}

/*
** Return true if the input string can be converted to a julianday.
*/
static int fossil_is_julianday(const char *zDate){
  return db_int(0, "SELECT EXISTS (SELECT julianday(%Q) AS jd WHERE jd IS NOT NULL)", zDate);
}

/*
** COMMAND: timeline
**
** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS?
**
** Print a summary of activity going backwards in date and time
................................................................................
  const char *zOffset;
  const char *zType;
  char *zOrigin;
  char *zDate;
  Blob sql;
  int objid = 0;
  Blob uuid;
  int mode = TIMELINE_MODE_NONE;
  int verboseFlag = 0 ;
  int iOffset;
  const char *zFilePattern = 0;
  Blob treeName;

  verboseFlag = find_option("verbose","v", 0)!=0;
  if( !verboseFlag){
................................................................................

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

  if( g.argc>=4 ){
    k = strlen(g.argv[2]);
    if( strncmp(g.argv[2],"before",k)==0 ){
      mode = TIMELINE_MODE_BEFORE;
    }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
      mode = TIMELINE_MODE_AFTER;
    }else if( strncmp(g.argv[2],"descendants",k)==0 ){
      mode = TIMELINE_MODE_CHILDREN;
    }else if( strncmp(g.argv[2],"children",k)==0 ){
      mode = TIMELINE_MODE_CHILDREN;
    }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
      mode = TIMELINE_MODE_PARENTS;
    }else if( strncmp(g.argv[2],"parents",k)==0 ){
      mode = TIMELINE_MODE_PARENTS;
    }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{
................................................................................
  }else{
    zOrigin = "now";
  }
  k = strlen(zOrigin);
  blob_zero(&uuid);
  blob_append(&uuid, zOrigin, -1);
  if( fossil_strcmp(zOrigin, "now")==0 ){
    if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
      fossil_fatal("cannot compute descendants or ancestors of a date");
    }
    zDate = mprintf("(SELECT datetime('now'))");
  }else if( strncmp(zOrigin, "current", k)==0 ){
    if( !g.localOpen ){
      fossil_fatal("must be within a local checkout to use 'current'");
    }
    objid = db_lget_int("checkout",0);
    zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid);
  }else if( name_to_uuid(&uuid, 0, "*")==0 ){
    objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
    zDate = mprintf("(SELECT mtime FROM event WHERE objid=%d)", objid);
  }else if( fossil_is_julianday(zOrigin) ){
    const char *zShift = "";
    if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
      fossil_fatal("cannot compute descendants or ancestors of a date");
    }
    if( mode==TIMELINE_MODE_NONE ){
      if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
    }
    zDate = mprintf("(SELECT julianday(%Q%s, fromLocal()))", zOrigin, zShift);
  }else{
    fossil_fatal("unknown check-in or invalid date: %s", zOrigin);
  }

  if( zFilePattern ){
    if( zType==0 ){
      /* When zFilePattern is specified and type is not specified, only show
       * file check-ins */
      zType="ci";
................................................................................
    if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
      /* When zTreeName refers to g.zLocalRoot, it's like not specifying
       * zFilePattern. */
      zFilePattern = 0;
    }
  }

  if( mode==TIMELINE_MODE_NONE ) mode = TIMELINE_MODE_BEFORE;
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_tty(), -1);
  blob_append_sql(&sql, "\n  AND event.mtime %s %s",
     ( mode==TIMELINE_MODE_BEFORE ||
       mode==TIMELINE_MODE_PARENTS ) ? "<=" : ">=", zDate /*safe-for-%s*/
  );

  if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
    db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
    if( mode==TIMELINE_MODE_CHILDREN ){
      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') ){

Changes to src/undo.c.

475
476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491
492
  undo_available = db_lget_int("undo_available", 0);
  if( dryRunFlag ){
    if( undo_available==0 ){
      fossil_print("No undo or redo is available\n");
    }else{
      Stmt q;
      int nChng = 0;

      zCmd = undo_available==1 ? "undo" : "redo";
      fossil_print("A %s is available for the following command:\n\n"
                   "   %s %s\n\n",
                   zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
      db_prepare(&q,
        "SELECT existsflag, pathname FROM undo ORDER BY pathname"
      );
      while( db_step(&q)==SQLITE_ROW ){
        if( nChng==0 ){
          fossil_print("The following file changes would occur if the "
                       "command above is %sne:\n\n", zCmd);







>

|

|







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  undo_available = db_lget_int("undo_available", 0);
  if( dryRunFlag ){
    if( undo_available==0 ){
      fossil_print("No undo or redo is available\n");
    }else{
      Stmt q;
      int nChng = 0;
      const char *zArticle = undo_available==1 ? "An" : "A";
      zCmd = undo_available==1 ? "undo" : "redo";
      fossil_print("%s %s is available for the following command:\n\n"
                   "   %s %s\n\n",
                   zArticle, zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
      db_prepare(&q,
        "SELECT existsflag, pathname FROM undo ORDER BY pathname"
      );
      while( db_step(&q)==SQLITE_ROW ){
        if( nChng==0 ){
          fossil_print("The following file changes would occur if the "
                       "command above is %sne:\n\n", zCmd);

Changes to src/unversioned.c.

188
189
190
191
192
193
194












195
196
197

198
199
200
201
202
203
204
...
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
...
269
270
271
272
273
274
275



276
277
278
279
280
281
282
...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
...
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
  if( find_option("dryrun","n",0)!=0 ){
    syncFlags |= SYNC_UV_DRYRUN | SYNC_UV_TRACE | SYNC_VERBOSE;
  }
  return syncFlags;
}

/*












** COMMAND: unversioned
**
** Usage: %fossil unversioned SUBCOMMAND ARGS...

**
** Unversioned files (UV-files) are artifacts that are synced and are available
** for download but which do not preserve history.  Only the most recent version
** of each UV-file is retained.  Changes to an UV-file are permanent and cannot
** be undone, so use appropriate caution with this command.
**
** Subcommands:
................................................................................
**
**    cat FILE ...         Concatenate the content of FILEs to stdout.
**
**    edit FILE            Bring up FILE in a text editor for modification.
**
**    export FILE OUTPUT   Write the content of FILE into OUTPUT on disk
**
**    list | ls            Show all unversioned files held in the local repository.

**
**    revert ?URL?         Restore the state of all unversioned files in the local
**                         repository to match the remote repository URL.


**                         Options:
**                            -v|--verbose     Extra diagnostic output
**                            -n|--dryrun      Show what would have happened
**
**    rm FILE ...          Remove an unversioned files from the local repository.
**                         Changes are not pushed to other repositories until
**                         the next sync. 
**
**    sync ?URL?           Synchronize the state of all unversioned files with
**                         the remote repository URL.  The most recent version of
**                         each file is propagate to all repositories and all
**                         prior versions are permanently forgotten.

**                         Options:
**                            -v|--verbose     Extra diagnostic output
**                            -n|--dryrun      Show what would have happened
**
**    touch FILE ...       Update the TIMESTAMP on all of the listed files
**
** Options:
**
**   --mtime TIMESTAMP     Use TIMESTAMP instead of "now" for "add" and "rm".

*/
void unversioned_cmd(void){
  const char *zCmd;
  int nCmd;
  const char *zMtime = find_option("mtime", 0, 1);
  sqlite3_int64 mtime;
  db_find_and_open_repository(0, 0);
................................................................................
    db_begin_transaction();
    content_rcvid_init("#!fossil unversioned add");
    for(i=3; i<g.argc; i++){
      zIn = zAs ? zAs : g.argv[i];
      if( zIn[0]==0 || zIn[0]=='/' || !file_is_simple_pathname(zIn,1) ){
        fossil_fatal("'%Q' is not an acceptable filename", zIn);
      }



      blob_init(&file,0,0);
      blob_read_from_file(&file, g.argv[i]);
      unversioned_write(zIn, &file, mtime);
      blob_reset(&file);
    }
    db_end_transaction(0);
  }else if( memcmp(zCmd, "cat", nCmd)==0 ){
................................................................................
    }
    db_finalize(&q);
  }else if( memcmp(zCmd, "revert", nCmd)==0 ){
    unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
    g.argv[1] = "sync";
    g.argv[2] = "--uv-noop";
    sync_unversioned(syncFlags);
  }else if( memcmp(zCmd, "rm", nCmd)==0 ){
    int i;
    verify_all_options();
    db_begin_transaction();
    for(i=3; i<g.argc; i++){
      db_multi_exec(
        "UPDATE unversioned"
        "   SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name=%Q",
................................................................................
        "UPDATE unversioned SET mtime=%lld WHERE name=%Q",
        mtime, g.argv[i]
      );
    }
    db_unset("uv-hash", 0);
    db_end_transaction(0);
  }else{
    usage("add|cat|edit|export|ls|revert|rm|sync|touch");
  }
}

/*
** WEBPAGE: uvlist
**
** Display a list of all unversioned files in the repository.







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



>







 







|
>

|
|
>
>




|

|


|
|
|
>








|
>







 







>
>
>







 







|







 







|







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
...
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
...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
  if( find_option("dryrun","n",0)!=0 ){
    syncFlags |= SYNC_UV_DRYRUN | SYNC_UV_TRACE | SYNC_VERBOSE;
  }
  return syncFlags;
}

/*
** Return true if the zName contains any whitespace
*/
static int contains_whitespace(const char *zName){
  while( zName[0] ){
    if( fossil_isspace(zName[0]) ) return 1;
    zName++;
  }
  return 0;
}

/*
** COMMAND: uv*
** COMMAND: unversioned
**
** Usage: %fossil unversioned SUBCOMMAND ARGS...
**    or: %fossil uv SUBCOMMAND ARGS..
**
** Unversioned files (UV-files) are artifacts that are synced and are available
** for download but which do not preserve history.  Only the most recent version
** of each UV-file is retained.  Changes to an UV-file are permanent and cannot
** be undone, so use appropriate caution with this command.
**
** Subcommands:
................................................................................
**
**    cat FILE ...         Concatenate the content of FILEs to stdout.
**
**    edit FILE            Bring up FILE in a text editor for modification.
**
**    export FILE OUTPUT   Write the content of FILE into OUTPUT on disk
**
**    list | ls            Show all unversioned files held in the local
**                         repository.
**
**    revert ?URL?         Restore the state of all unversioned files in the
**                         local repository to match the remote repository
**                         URL.
**
**                         Options:
**                            -v|--verbose     Extra diagnostic output
**                            -n|--dryrun      Show what would have happened
**
**    remove | rm FILE ... Remove unversioned files from the local repository.
**                         Changes are not pushed to other repositories until
**                         the next sync.
**
**    sync ?URL?           Synchronize the state of all unversioned files with
**                         the remote repository URL.  The most recent version
**                         of each file is propagate to all repositories and
**                         all prior versions are permanently forgotten.
**
**                         Options:
**                            -v|--verbose     Extra diagnostic output
**                            -n|--dryrun      Show what would have happened
**
**    touch FILE ...       Update the TIMESTAMP on all of the listed files
**
** Options:
**
**   --mtime TIMESTAMP     Use TIMESTAMP instead of "now" for the "add",
**                         "edit", "remove", and "touch" subcommands.
*/
void unversioned_cmd(void){
  const char *zCmd;
  int nCmd;
  const char *zMtime = find_option("mtime", 0, 1);
  sqlite3_int64 mtime;
  db_find_and_open_repository(0, 0);
................................................................................
    db_begin_transaction();
    content_rcvid_init("#!fossil unversioned add");
    for(i=3; i<g.argc; i++){
      zIn = zAs ? zAs : g.argv[i];
      if( zIn[0]==0 || zIn[0]=='/' || !file_is_simple_pathname(zIn,1) ){
        fossil_fatal("'%Q' is not an acceptable filename", zIn);
      }
      if( contains_whitespace(zIn) ){
        fossil_fatal("names of unversioned files may not contain whitespace");
      }
      blob_init(&file,0,0);
      blob_read_from_file(&file, g.argv[i]);
      unversioned_write(zIn, &file, mtime);
      blob_reset(&file);
    }
    db_end_transaction(0);
  }else if( memcmp(zCmd, "cat", nCmd)==0 ){
................................................................................
    }
    db_finalize(&q);
  }else if( memcmp(zCmd, "revert", nCmd)==0 ){
    unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
    g.argv[1] = "sync";
    g.argv[2] = "--uv-noop";
    sync_unversioned(syncFlags);
  }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 ){
    int i;
    verify_all_options();
    db_begin_transaction();
    for(i=3; i<g.argc; i++){
      db_multi_exec(
        "UPDATE unversioned"
        "   SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name=%Q",
................................................................................
        "UPDATE unversioned SET mtime=%lld WHERE name=%Q",
        mtime, g.argv[i]
      );
    }
    db_unset("uv-hash", 0);
    db_end_transaction(0);
  }else{
    usage("add|cat|edit|export|list|revert|remove|sync|touch");
  }
}

/*
** WEBPAGE: uvlist
**
** Display a list of all unversioned files in the repository.

Changes to src/utf8.c.

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#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;
  }








|







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#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;
  }

Changes to src/vfile.c.

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
          file_set_mtime(zName, desiredMtime);
          currentMtime = file_wd_mtime(zName);
        }
      }
    }
#ifndef _WIN32
    if( chnged==0 || chnged==6 || chnged==7 || chnged==8 || chnged==9 ){
      if( origPerm == currentPerm ){
        chnged = 0;
      }else if( currentPerm == PERM_EXE ){
        chnged = 6;
      }else if( currentPerm == PERM_LNK ){
        chnged = 7;
      }else if( origPerm == PERM_EXE ){
        chnged = 8;
      }else if( origPerm == PERM_LNK ){
        chnged = 9;
      }
    }
#endif
    if( currentMtime!=oldMtime || chnged!=oldChnged ){
      db_multi_exec("UPDATE vfile SET mtime=%lld, chnged=%d WHERE id=%d",
                    currentMtime, chnged, id);
................................................................................
        promptFlag = 0;
      } else if( cReply!='y' && cReply!='Y' ){
        blob_reset(&content);
        continue;
      }
    }
    if( verbose ) fossil_print("%s\n", &zName[nRepos]);
    if( file_wd_isdir(zName) == 1 ){
      /*TODO(dchest): remove directories? */
      fossil_fatal("%s is directory, cannot overwrite\n", zName);
    }
    if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(0)) ){
      file_delete(zName);
    }
    if( isLink ){







|

|

|

|

|







 







|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
          file_set_mtime(zName, desiredMtime);
          currentMtime = file_wd_mtime(zName);
        }
      }
    }
#ifndef _WIN32
    if( chnged==0 || chnged==6 || chnged==7 || chnged==8 || chnged==9 ){
      if( origPerm==currentPerm ){
        chnged = 0;
      }else if( currentPerm==PERM_EXE ){
        chnged = 6;
      }else if( currentPerm==PERM_LNK ){
        chnged = 7;
      }else if( origPerm==PERM_EXE ){
        chnged = 8;
      }else if( origPerm==PERM_LNK ){
        chnged = 9;
      }
    }
#endif
    if( currentMtime!=oldMtime || chnged!=oldChnged ){
      db_multi_exec("UPDATE vfile SET mtime=%lld, chnged=%d WHERE id=%d",
                    currentMtime, chnged, id);
................................................................................
        promptFlag = 0;
      } else if( cReply!='y' && cReply!='Y' ){
        blob_reset(&content);
        continue;
      }
    }
    if( verbose ) fossil_print("%s\n", &zName[nRepos]);
    if( file_wd_isdir(zName)==1 ){
      /*TODO(dchest): remove directories? */
      fossil_fatal("%s is directory, cannot overwrite\n", zName);
    }
    if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(0)) ){
      file_delete(zName);
    }
    if( isLink ){

Changes to src/winhttp.c.

22
23
24
25
26
27
28














29
30
31
32
33
34
35
..
68
69
70
71
72
73
74









































75
76
77
78
79
80
81
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
...
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
...
322
323
324
325
326
327
328


















329
330
331
332
333
334
335
336
337
338
339
340
341
342
...
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
#include "config.h"
#ifdef _WIN32
/* This code is for win32 only */
#include <windows.h>
#include <process.h>
#include "winhttp.h"















/*
** The HttpRequest structure holds information about each incoming
** HTTP request.
*/
typedef struct HttpRequest HttpRequest;
struct HttpRequest {
  int id;                /* ID counter */
................................................................................
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;
................................................................................
end_request:
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  file_delete(zRequestFName);
  file_delete(zReplyFName);
  file_delete(zCmdFName);
  free(p);
}

/*
** Process a single incoming SCGI request.
*/
static void win32_scgi_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
................................................................................

end_request:
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  file_delete(zRequestFName);
  file_delete(zReplyFName);
  free(p);
}


/*
** Start a listening socket and process incoming HTTP requests on
** that socket.
*/
................................................................................
  const char *zStopper,     /* Stop server when this file is exists (Or NULL) */
  const char *zBaseUrl,     /* The --baseurl option, or NULL */
  const char *zNotFound,    /* The --notfound option, or NULL */
  const char *zFileGlob,    /* The --fileglob option, or NULL */
  const char *zIpAddr,      /* Bind to this IP address, if not NULL */
  int flags                 /* One or more HTTP_SERVER_ flags */
){

  WSADATA wd;
  SOCKET s = INVALID_SOCKET;
  SOCKADDR_IN addr;
  int idCnt = 0;
  int iPort = mnPort;
  Blob options;
  wchar_t zTmpPath[MAX_PATH];

  if( zStopper ) file_delete(zStopper);
  blob_zero(&options);
  if( zBaseUrl ){
    blob_appendf(&options, " --baseurl %s", zBaseUrl);
  }
  if( zNotFound ){
    blob_appendf(&options, " --notfound %s", zNotFound);
  }
................................................................................
               (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);
  for(;;){
    SOCKET client;
    SOCKADDR_IN client_addr;
    HttpRequest *p;
    int len = sizeof(client_addr);
    int wsaError;

    client = accept(s, (struct sockaddr*)&client_addr, &len);
    if( client==INVALID_SOCKET ){
      /* If the service control handler has closed the listener socket,
      ** cleanup and return, otherwise report a fatal error. */
................................................................................
        WSACleanup();
        return;
      }else{
        closesocket(s);
        WSACleanup();
        fossil_fatal("error from accept()");
      }
    }else if( zStopper && file_size(zStopper)>=0 ){
      break;
    }
    p = fossil_malloc( sizeof(*p) );
    p->id = ++idCnt;
    p->s = client;
    p->addr = client_addr;
    p->flags = flags;
    p->zOptions = blob_str(&options);
    if( flags & HTTP_SERVER_SCGI ){
      _beginthread(win32_scgi_request, 0, (void*)p);
    }else{
      _beginthread(win32_http_request, 0, (void*)p);
    }
  }
  closesocket(s);
  WSACleanup();


}

/*
** The HttpService structure is used to pass information to the service main
** function and to the service control handler function.
*/
typedef struct HttpService HttpService;







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







 







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







 







|







 







|







 







>








<







 







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






|







 







<
<

|
|
|
|
|
|

|

|




>
>







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
..
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
...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
...
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
...
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
#include "config.h"
#ifdef _WIN32
/* This code is for win32 only */
#include <windows.h>
#include <process.h>
#include "winhttp.h"

/*
** The HttpServer structure holds information about an instance of
** the HTTP server itself.
*/
typedef struct HttpServer HttpServer;
struct HttpServer {
  HANDLE hStoppedEvent; /* Event to signal when server is stopped,
                        ** must be closed by callee. */
  char *zStopper;       /* The stopper file name, must be freed by
                        ** callee. */
  SOCKET listener;      /* Socket on which the server is listening,
                        ** may be closed by callee. */
};

/*
** The HttpRequest structure holds information about each incoming
** HTTP request.
*/
typedef struct HttpRequest HttpRequest;
struct HttpRequest {
  int id;                /* ID counter */
................................................................................
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);
}

/*
** Make sure the server stops as soon as possible after the stopper file
** is found.  If there is no stopper file name, do nothing.
*/
static void win32_server_stopper(void *pAppData){
  HttpServer *p = (HttpServer*)pAppData;
  if( p!=0 ){
    HANDLE hStoppedEvent = p->hStoppedEvent;
    const char *zStopper = p->zStopper;
    SOCKET listener = p->listener;
    if( hStoppedEvent!=NULL && zStopper!=0 && listener!=INVALID_SOCKET ){
      while( 1 ){
        DWORD dwResult = WaitForMultipleObjectsEx(1, &hStoppedEvent, FALSE,
                                                  1000, TRUE);
        if( dwResult!=WAIT_IO_COMPLETION && dwResult!=WAIT_TIMEOUT ){
          /* The event is either invalid, signaled, or abandoned.  Bail
          ** out now because those conditions should indicate the parent
          ** thread is dead or dying. */
          break;
        }
        if( file_size(zStopper)>=0 ){
          /* The stopper file has been found.  Attempt to close the server
          ** listener socket now and then exit. */
          closesocket(listener);
          p->listener = INVALID_SOCKET;
          break;
        }
      }
    }
    if( hStoppedEvent!=NULL ){
      CloseHandle(hStoppedEvent);
      p->hStoppedEvent = NULL;
    }
    if( zStopper!=0 ){
      fossil_free(p->zStopper);
      p->zStopper = 0;
    }
    fossil_free(p);
  }
}

/*
** Process a single incoming HTTP request.
*/
static void win32_http_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
  FILE *in = 0, *out = 0;
................................................................................
end_request:
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  file_delete(zRequestFName);
  file_delete(zReplyFName);
  file_delete(zCmdFName);
  fossil_free(p);
}

/*
** Process a single incoming SCGI request.
*/
static void win32_scgi_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
................................................................................

end_request:
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  file_delete(zRequestFName);
  file_delete(zReplyFName);
  fossil_free(p);
}


/*
** Start a listening socket and process incoming HTTP requests on
** that socket.
*/
................................................................................
  const char *zStopper,     /* Stop server when this file is exists (Or NULL) */
  const char *zBaseUrl,     /* The --baseurl option, or NULL */
  const char *zNotFound,    /* The --notfound option, or NULL */
  const char *zFileGlob,    /* The --fileglob option, or NULL */
  const char *zIpAddr,      /* Bind to this IP address, if not NULL */
  int flags                 /* One or more HTTP_SERVER_ flags */
){
  HANDLE hStoppedEvent;
  WSADATA wd;
  SOCKET s = INVALID_SOCKET;
  SOCKADDR_IN addr;
  int idCnt = 0;
  int iPort = mnPort;
  Blob options;
  wchar_t zTmpPath[MAX_PATH];


  blob_zero(&options);
  if( zBaseUrl ){
    blob_appendf(&options, " --baseurl %s", zBaseUrl);
  }
  if( zNotFound ){
    blob_appendf(&options, " --notfound %s", zNotFound);
  }
................................................................................
               (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");
  /* Create an event used to signal when this server is exiting. */
  hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  assert( hStoppedEvent!=NULL );
  /* If there is a stopper file name, start the dedicated thread now.
  ** It will attempt to close the listener socket within 1 second of
  ** the stopper file being created. */
  if( zStopper ){
    HttpServer *pServer = fossil_malloc(sizeof(HttpServer));
    memset(pServer, 0, sizeof(HttpServer));
    DuplicateHandle(GetCurrentProcess(), hStoppedEvent,
                    GetCurrentProcess(), &pServer->hStoppedEvent,
                    0, FALSE, DUPLICATE_SAME_ACCESS);
    assert( pServer->hStoppedEvent!=NULL );
    pServer->zStopper = fossil_strdup(zStopper);
    pServer->listener = s;
    file_delete(zStopper);
    _beginthread(win32_server_stopper, 0, (void*)pServer);
  }
  /* Set the service status to running and pass the listener socket to the
  ** service handling procedures. */
  win32_http_service_running(s);
  for(;;){
    SOCKET client;
    SOCKADDR_IN client_addr;
    HttpRequest *pRequest;
    int len = sizeof(client_addr);
    int wsaError;

    client = accept(s, (struct sockaddr*)&client_addr, &len);
    if( client==INVALID_SOCKET ){
      /* If the service control handler has closed the listener socket,
      ** cleanup and return, otherwise report a fatal error. */
................................................................................
        WSACleanup();
        return;
      }else{
        closesocket(s);
        WSACleanup();
        fossil_fatal("error from accept()");
      }


    }
    pRequest = fossil_malloc(sizeof(HttpRequest));
    pRequest->id = ++idCnt;
    pRequest->s = client;
    pRequest->addr = client_addr;
    pRequest->flags = flags;
    pRequest->zOptions = blob_str(&options);
    if( flags & HTTP_SERVER_SCGI ){
      _beginthread(win32_scgi_request, 0, (void*)pRequest);
    }else{
      _beginthread(win32_http_request, 0, (void*)pRequest);
    }
  }
  closesocket(s);
  WSACleanup();
  SetEvent(hStoppedEvent);
  CloseHandle(hStoppedEvent);
}

/*
** The HttpService structure is used to pass information to the service main
** function and to the service control handler function.
*/
typedef struct HttpService HttpService;

Changes to src/zip.c.

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
  if( zDir && zDir[0] ){
    blob_appendf(&filename, "%s/", zDir);
  }
  nPrefix = blob_size(&filename);

  pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
  if( pManifest ){

    char *zName;
    zip_set_timedate(pManifest->rDate);



    if( (pInclude==0 || glob_match(pInclude, "manifest"))
     && !glob_match(pExclude, "manifest")
     && db_get_boolean("manifest", 0)
    ){
















      blob_append(&filename, "manifest", -1);
      zName = blob_str(&filename);
      zip_add_folders(zName);


      sha1sum_blob(&mfile, &hash);


      sterilize_manifest(&mfile);
      zip_add_file(zName, &mfile, 0);


      blob_reset(&mfile);

      blob_append(&hash, "\n", 1);
      blob_resize(&filename, nPrefix);
      blob_append(&filename, "manifest.uuid", -1);
      zName = blob_str(&filename);

      zip_add_file(zName, &hash, 0);
      blob_reset(&hash);












    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;
      fid = uuid_to_rid(pFile->zUuid, 0);







>
|

>
>
>
|
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
|
>
>
|
|
>
>

>
|
|
|
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>







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
  if( zDir && zDir[0] ){
    blob_appendf(&filename, "%s/", zDir);
  }
  nPrefix = blob_size(&filename);

  pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
  if( pManifest ){
    int flg, eflg = 0;
    char *zName = 0;
    zip_set_timedate(pManifest->rDate);
    flg = db_get_manifest_setting();
    if( flg ){
      /* eflg is the effective flags, taking include/exclude into account */
      if( (pInclude==0 || glob_match(pInclude, "manifest"))
       && !glob_match(pExclude, "manifest")


       && (flg & MFESTFLG_RAW) ){
        eflg |= MFESTFLG_RAW;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.uuid"))
       && !glob_match(pExclude, "manifest.uuid")
       && (flg & MFESTFLG_UUID) ){
        eflg |= MFESTFLG_UUID;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
       && !glob_match(pExclude, "manifest.tags")
       && (flg & MFESTFLG_TAGS) ){
        eflg |= MFESTFLG_TAGS;
      }

      if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
        if( eflg & MFESTFLG_RAW ){
          blob_append(&filename, "manifest", -1);
          zName = blob_str(&filename);
          zip_add_folders(zName);
        }
        if( eflg & MFESTFLG_UUID ){
          sha1sum_blob(&mfile, &hash);
        }
        if( eflg & MFESTFLG_RAW ){
          sterilize_manifest(&mfile);
          zip_add_file(zName, &mfile, 0);
        }
      }
      blob_reset(&mfile);
      if( eflg & MFESTFLG_UUID ){
        blob_append(&hash, "\n", 1);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.uuid", -1);
        zName = blob_str(&filename);
        zip_add_folders(zName);
        zip_add_file(zName, &hash, 0);
        blob_reset(&hash);
      }
      if( eflg & MFESTFLG_TAGS ){
        Blob tagslist;
        blob_zero(&tagslist);
        get_checkin_taglist(rid, &tagslist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.tags", -1);
        zName = blob_str(&filename);
        zip_add_folders(zName);
        zip_add_file(zName, &tagslist, 0);
        blob_reset(&tagslist);
      }
    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;
      fid = uuid_to_rid(pFile->zUuid, 0);

Changes to test/delta1.test.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48









49
50
51
  if {[file isdir $f]} continue
  set base [file root [file tail $f]]
  set f1 [read_file $f]
  write_file t1 $f1
  for {set i 0} {$i<100} {incr i} {
    write_file t2 [random_changes $f1 1 1 0 0.1]
    fossil test-delta t1 t2
    test delta-$base-$i-1 {$RESULT=="ok"}
    write_file t2 [random_changes $f1 1 1 0 0.2]
    fossil test-delta t1 t2
    test delta-$base-$i-2 {$RESULT=="ok"}
    write_file t2 [random_changes $f1 1 1 0 0.4]
    fossil test-delta t1 t2
    test delta-$base-$i-3 {$RESULT=="ok"}
  }
}










###############################################################################

test_cleanup







|


|


|



>
>
>
>
>
>
>
>
>



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
  if {[file isdir $f]} continue
  set base [file root [file tail $f]]
  set f1 [read_file $f]
  write_file t1 $f1
  for {set i 0} {$i<100} {incr i} {
    write_file t2 [random_changes $f1 1 1 0 0.1]
    fossil test-delta t1 t2
    test delta-$base-$i-1 {[normalize_result]=="ok"}
    write_file t2 [random_changes $f1 1 1 0 0.2]
    fossil test-delta t1 t2
    test delta-$base-$i-2 {[normalize_result]=="ok"}
    write_file t2 [random_changes $f1 1 1 0 0.4]
    fossil test-delta t1 t2
    test delta-$base-$i-3 {[normalize_result]=="ok"}
  }
}

set empties { "" "" "" a a "" }
set i 0
foreach {f1 f2} $empties {
  incr i
  write_file t1 $f1
  write_file t2 $f2
  fossil test-delta t1 t2
  test delta-empty-$i {[normalize_result]=="ok"}
}
###############################################################################

test_cleanup

Added test/fake-editor.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
#
# Copyright (c) 2016 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 fake text editor for use by tests.  To customize its behavior,
# set the FAKE_EDITOR_SCRIPT environment variable prior to evaluating this
# script file.  If FAKE_EDITOR_SCRIPT environment variable is not set, the
# default behavior will be used.  The default behavior is to append the
# process identifier and the current time, in seconds, to the file data.
#

if {![info exists argv] || [llength $argv] != 1} {
  error "Usage: \"[info nameofexecutable]\" \"[info script]\" <fileName>"
}

###############################################################################

proc makeBinaryChannel { channel } {
  fconfigure $channel -encoding binary -translation binary
}

proc readFile { fileName } {
  set channel [open $fileName RDONLY]
  makeBinaryChannel $channel
  set result [read $channel]
  close $channel
  return $result
}

proc writeFile { fileName data } {
  set channel [open $fileName {WRONLY CREAT TRUNC}]
  makeBinaryChannel $channel
  puts -nonewline $channel $data
  close $channel
  return ""
}

###############################################################################

set fileName [lindex $argv 0]

if {[file exists $fileName]} then {
  set data [readFile $fileName]
} else {
  set data ""
}

###############################################################################

if {[info exists env(FAKE_EDITOR_SCRIPT)]} {
  #
  # NOTE: If an error is caught while evaluating this script, catch
  #       it and return, which will also skip writing the (possibly
  #       modified) content back to the original file.
  #
  set script $env(FAKE_EDITOR_SCRIPT)
  set code [catch $script error]

  if {$code != 0} then {
    if {[info exists env(FAKE_EDITOR_VERBOSE)]} {
      if {[info exists errorInfo]} {
        puts stdout "ERROR ($code): $errorInfo"
      } else {
        puts stdout "ERROR ($code): $error"
      }
    }

    return
  }
} else {
  #
  # NOTE: The default behavior is to append the process identifier
  #       and the current time, in seconds, to the file data.
  #
  append data " " [pid] " " [clock seconds]
}

###############################################################################

writeFile $fileName $data

Changes to test/json.test.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Make sure we have a build with the json command at all and that it
# is not stubbed out. This assumes the current (as of 2016-01-27)
# practice of eliminating all trace of the fossil json command when
# not configured. If that changes, these conditions might not prevent
# the rest of this file from running.
fossil test-th-eval "hasfeature json"

if {$::RESULT ne "1"} then {
  puts "Fossil was not compiled with JSON support."
  test_cleanup_then_return
}

# We need a JSON parser to effectively test the JSON produced by
# fossil. It looks like the one from tcllib is exactly what we need.
# On ActiveTcl, add it with teacup. On other platforms, YMMV.







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Make sure we have a build with the json command at all and that it
# is not stubbed out. This assumes the current (as of 2016-01-27)
# practice of eliminating all trace of the fossil json command when
# not configured. If that changes, these conditions might not prevent
# the rest of this file from running.
fossil test-th-eval "hasfeature json"

if {[normalize_result] ne "1"} then {
  puts "Fossil was not compiled with JSON support."
  test_cleanup_then_return
}

# We need a JSON parser to effectively test the JSON produced by
# fossil. It looks like the one from tcllib is exactly what we need.
# On ActiveTcl, add it with teacup. On other platforms, YMMV.

Changes to test/mv-rm.test.

13
14
15
16
17
18
19


20
21
22
23
24
25
26
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
############################################################################
#
# MV / RM Commands
#



require_no_open_checkout

########################################
# Setup: Add Files and Commit          #
########################################








>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
############################################################################
#
# MV / RM Commands
#

set path [file dirname [info script]]

require_no_open_checkout

########################################
# Setup: Add Files and Commit          #
########################################

Added test/set-manifest.test.























































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#
# Copyright (c) 2016 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/
#
############################################################################
#
# Test manifest setting
#

# We need SHA1 to effectively test the manifest files produced by
# fossil. It looks like the one from tcllib is exactly what we need.
# On ActiveTcl, add it with teacup. On other platforms, YMMV.
# teacup install sha1
package require sha1

proc file_contains {fname match} {
  set fp [open $fname r]
  set contents [read $fp]
  close $fp
  set lines [split $contents "\n"]
  foreach line $lines {
    if {[regexp $match $line]} {
      return 1
    }
  }
  return 0
}

# We need a respository, so let it have one.
test_setup

#### Verify classic behavior of the manifest setting

# Setting is off by default, and there are no extra files.
fossil settings manifest
test "set-manifest-1" {[regexp {^manifest *$} $RESULT]}
set filelist [glob -nocomplain manifest*]
test "set-manifest-1-n" {[llength $filelist] == 0}

# Classic behavior: TRUE value creates manifest and manifest.uuid
set truths [list true on 1]
foreach v $truths {
  fossil settings manifest $v
  test "set-manifest-2-$v" {$RESULT eq ""}
  fossil settings manifest
  test "set-manifest-2-$v-a" {[regexp "^manifest\\s+\\(local\\)\\s+$v\\s*$" $RESULT]}
  set filelist [glob manifest*]
  test "set-manifest-2-$v-n" {[llength $filelist] == 2}
  foreach f $filelist {
    test "set-manifest-2-$v-f-$f" {[file isfile $f]}
  }
}

# ... and manifest.uuid is the checkout's hash
fossil info
regexp {(?m)^checkout:\s+([0-9a-f]{40})\s.*$} $RESULT ckoutline ckid
set uuid [string trim [read_file "manifest.uuid"]]
test "set-manifest-2-uuid" {$ckid eq $uuid}

# ... which is also the SHA1 of the file "manifest" before it was
# sterilized by appending an extra line when writing the file. The
# extra text begins with # and is a full line, so we'll just strip
# it with a brute-force substitution. This probably has the right
# effect even if the checkin was PGP-signed, but we don't have that
# setting turned on for this manifest in any case.
regsub {(?m)^#.*\n} [read_file "manifest"] "" manifest
set muuid [::sha1::sha1 $manifest]
test "set-manifest-2-manifest" {$muuid eq $uuid}


# Classic behavior: FALSE value removes manifest and manifest.uuid
set falses [list false off 0]
foreach v $falses {
  fossil settings manifest $v
  test "set-manifest-3-$v" {$RESULT eq ""}
  fossil settings manifest
  test "set-manifest-3-$v-a" {[regexp "^manifest\\s+\\(local\\)\\s+$v\\s*$" $RESULT]}
  set filelist [glob -nocomplain manifest*]
  test "set-manifest-3-$v-n" {[llength $filelist] == 0}
}


# Classic behavior: unset removes manifest and manifest.uuid
fossil unset manifest
test "set-manifest-4" {$RESULT eq ""}
fossil settings manifest
test "set-manifest-4-a" {[regexp {^manifest *$} $RESULT]}
set filelist [glob -nocomplain manifest*]
test "set-manifest-4-n" {[llength $filelist] == 0}


##### Tags Manifest feature extends the manifest setting

# Manifest Tags: use letters r, u, and t to select each of manifest,
# manifest.uuid, and manifest.tags files.
set truths [list r u t ru ut rt rut]
foreach v $truths {
  fossil settings manifest $v
  test "set-manifest-5-$v" {$RESULT eq ""}
  fossil settings manifest
  test "set-manifest-5-$v-a" {[regexp "^manifest\\s+\\(local\\)\\s+$v\\s*$" $RESULT]}
  set filelist [glob manifest*]
  test "set-manifest-5-$v-n" {[llength $filelist] == [string length $v]}
  foreach f $filelist {
    test "set-manifest-5-$v-f-$f" {[file isfile $f]}
  }
}

# Quick check for tags applied in trunk
test_file_contents "set-manifest-6" "manifest.tags" "branch trunk\ntag trunk\n"


##### Test manifest.tags file content updates after commits

# Explicitly set manifest.tags mode
fossil set manifest t
test "set-manifest-7-1" {[file isfile manifest.tags]}

# Add a tag and make sure it appears in manifest.tags
fossil tag add manifest-7-tag-1 tip
test "set-manifest-7-2" {[file_contains "manifest.tags" "^tag manifest-7-tag-1$"]}

# Add a file and make sure tag has disappeared from manifest.tags
write_file file1 "file1 contents"
fossil add file1
fossil commit -m "Added file1."
test "set-manifest-7-3" {![file_contains "manifest.tags" "^tag manifest-7-tag-1$"]}

# Add new tag and check that it is in manifest.tags
fossil tag add manifest-7-tag-2 tip
test "set-manifest-7-4" {[file_contains "manifest.tags" "^tag manifest-7-tag-2$"]}


##### Tags manifest branch= updates

# Add file, create new branch on commit and check that
# manifest.tags has been updated appropriately
write_file file3 "file3 contents"
fossil add file3
fossil commit -m "Added file3." --branch manifest-8-branch
test "set-manifest-8" {[file_contains "manifest.tags" "^branch manifest-8-branch$"]}


test_cleanup

Changes to test/settings-repo.test.

14
15
16
17
18
19
20


21
22


23
24
25
26
27
28
29
#   http://www.hwaci.com/drh/
#
############################################################################
#
# The "settings" and "unset" commands that may modify the repository.
#



require_no_open_checkout
set dir [file dirname [info script]]; test_setup



###############################################################################
#
# Complete syntax as tested:
#
#     fossil settings ?PROPERTY? ?VALUE? ?OPTIONS?
#     fossil unset PROPERTY ?OPTIONS?







>
>

<
>
>







14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
#   http://www.hwaci.com/drh/
#
############################################################################
#
# The "settings" and "unset" commands that may modify the repository.
#

set path [file dirname [info script]]

require_no_open_checkout


test_setup

###############################################################################
#
# Complete syntax as tested:
#
#     fossil settings ?PROPERTY? ?VALUE? ?OPTIONS?
#     fossil unset PROPERTY ?OPTIONS?

Changes to test/settings.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#   http://www.hwaci.com/drh/
#
############################################################################
#
# The "settings" and "unset" commands.
#

set dir [file dirname [info script]]; test_setup

###############################################################################
#
# Complete syntax as tested:
#
#     fossil settings ?PROPERTY? ?VALUE? ?OPTIONS?
#     fossil unset PROPERTY ?OPTIONS?







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#   http://www.hwaci.com/drh/
#
############################################################################
#
# The "settings" and "unset" commands.
#

set path [file dirname [info script]]; test_setup

###############################################################################
#
# Complete syntax as tested:
#
#     fossil settings ?PROPERTY? ?VALUE? ?OPTIONS?
#     fossil unset PROPERTY ?OPTIONS?

Added test/symlinks.test.



























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#
# Copyright (c) 2016 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/
#
############################################################################
#
# Symbolic link tests.
#

set path [file dirname [info script]]

if {$tcl_platform(platform) eq "windows"} {
  puts "Symlinks are not supported on Windows."
  test_cleanup_then_return
}

fossil test-th-eval --open-config "setting allow-symlinks"

if {![string is true -strict [normalize_result]]} {
  puts "Symlinks are not enabled."
  test_cleanup_then_return
}

require_no_open_checkout

###############################################################################

test_setup; set rootDir [file normalize [pwd]]

fossil test-th-eval --open-config {repository}
set repository [normalize_result]

if {[string length $repository] == 0} {
  puts "Detection of the open repository file failed."
  test_cleanup_then_return
}

#######################################
# Use symbolic link to a directory... #
#######################################

file mkdir [file join $rootDir subdirA]
exec ln -s [file join $rootDir subdirA] symdirA

###############################################################################

write_file [file join $rootDir subdirA f1.txt] "f1"
write_file [file join $rootDir subdirA f2.txt] "f2"

test symlinks-dir-1 {[file exists [file join $rootDir subdirA f1.txt]] eq 1}
test symlinks-dir-2 {[file exists [file join $rootDir symdirA f1.txt]] eq 1}
test symlinks-dir-3 {[file exists [file join $rootDir subdirA f2.txt]] eq 1}
test symlinks-dir-4 {[file exists [file join $rootDir symdirA f2.txt]] eq 1}

fossil add [file join $rootDir symdirA f1.txt]
fossil commit -m "c1"

###############################################################################

fossil ls
test symlinks-dir-5 {[normalize_result] eq "symdirA/f1.txt"}

###############################################################################

fossil extras
test symlinks-dir-6 {[normalize_result] eq \
"subdirA/f1.txt\nsubdirA/f2.txt\nsymdirA/f2.txt"}

###############################################################################

fossil close
file delete [file join $rootDir subdirA f1.txt]

test symlinks-dir-7 {[file exists [file join $rootDir subdirA f1.txt]] eq 0}
test symlinks-dir-8 {[file exists [file join $rootDir symdirA f1.txt]] eq 0}
test symlinks-dir-9 {[file exists [file join $rootDir subdirA f2.txt]] eq 1}
test symlinks-dir-10 {[file exists [file join $rootDir symdirA f2.txt]] eq 1}

###############################################################################

fossil open $repository
set code [catch {file readlink [file join $rootDir symdirA]} result]

test symlinks-dir-11 {$code == 0}
test symlinks-dir-12 {$result eq [file join $rootDir subdirA]}
test symlinks-dir-13 {[file exists [file join $rootDir subdirA f1.txt]] eq 1}
test symlinks-dir-14 {[file exists [file join $rootDir symdirA f1.txt]] eq 1}
test symlinks-dir-15 {[file exists [file join $rootDir subdirA f2.txt]] eq 1}
test symlinks-dir-16 {[file exists [file join $rootDir symdirA f2.txt]] eq 1}

###############################################################################
#
# TODO: Add tests for symbolic links as files here, including tests with the
#       "allow-symlinks" setting on and off.
#
###############################################################################

test_cleanup

Changes to test/tester.tcl.

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
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
...
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
...
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
...
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
...
730
731
732
733
734
735
736










































































737
738
739
740
741
742
743
# Sets the CODE and RESULT global variables for use in
# test expressions.
#
proc fossil_maybe_answer {answer args} {
  global fossilexe
  set cmd $fossilexe
  set expectError 0
  if {[lindex $args end] eq "-expectError"} {

    set expectError 1
    set args [lrange $args 0 end-1]







  }
  foreach a $args {
    lappend cmd $a
  }
  protOut $cmd

  flush stdout
  if {[string length $answer] > 0} {
    protOut $answer
    set prompt_file [file join $::tempPath fossil_prompt_answer]
    write_file $prompt_file $answer\n



    set rc [catch {eval exec $cmd <$prompt_file} result]

    file delete $prompt_file
  } else {



    set rc [catch {eval exec $cmd} result]

  }
  global RESULT CODE
  set CODE $rc
  if {($rc && !$expectError) || (!$rc && $expectError)} {
    protOut "ERROR: $result" 1
  } elseif {$::VERBOSE} {
    protOut "RESULT: $result"
................................................................................
      keep-glob \
      manifest \
      th1-setup \
      th1-uri-regexp]

  fossil test-th-eval "hasfeature tcl"

  if {$::RESULT eq "1"} {
    lappend result tcl-setup
  }

  return [lsort -dictionary $result]
}

# Returns the list of all supported settings.
................................................................................
      th1-setup \
      th1-uri-regexp \
      uv-sync \
      web-browser]

  fossil test-th-eval "hasfeature legacyMvRm"

  if {$::RESULT eq "1"} {
    lappend result mv-rm-files
  }

  fossil test-th-eval "hasfeature tcl"

  if {$::RESULT eq "1"} {
    lappend result tcl tcl-setup
  }

  fossil test-th-eval "hasfeature th1Docs"

  if {$::RESULT eq "1"} {
    lappend result th1-docs
  }

  fossil test-th-eval "hasfeature th1Hooks"

  if {$::RESULT eq "1"} {
    lappend result th1-hooks
  }

  return [lsort -dictionary $result]
}

# Return true if two files are the same
................................................................................
  }
}

# This procedure only returns non-zero if the Tcl integration feature was
# enabled at compile-time and is now enabled at runtime.
proc is_tcl_usable_by_fossil {} {
  fossil test-th-eval "hasfeature tcl"
  if {$::RESULT ne "1"} {return 0}
  fossil test-th-eval "setting tcl"
  if {$::RESULT eq "1"} {return 1}
  fossil test-th-eval --open-config "setting tcl"
  if {$::RESULT eq "1"} {return 1}
  return [info exists ::env(TH1_ENABLE_TCL)]
}

# This procedure only returns non-zero if the TH1 hooks feature was enabled
# at compile-time and is now enabled at runtime.
proc are_th1_hooks_usable_by_fossil {} {
  fossil test-th-eval "hasfeature th1Hooks"
  if {$::RESULT ne "1"} {return 0}
  fossil test-th-eval "setting th1-hooks"
  if {$::RESULT eq "1"} {return 1}
  fossil test-th-eval --open-config "setting th1-hooks"
  if {$::RESULT eq "1"} {return 1}
  return [info exists ::env(TH1_ENABLE_HOOKS)]
}

# This (rarely used) procedure is designed to run a test within the Fossil
# source checkout (e.g. one that does NOT modify any state), while saving
# and restoring the current directory (e.g. one used when running a test
# file outside of the Fossil source checkout).  Please do NOT use this
................................................................................

  #
  # NOTE: Check if we can use any of the environment variables.
  #
  foreach name $names {
    set value [getEnvironmentVariable $name]

    if {[string length $value] > 0} then {
      set value [file normalize $value]

      if {[file exists $value] && [file isdirectory $value]} then {
        return $value
      }
    }
  }

  #
  # NOTE: On non-Windows systems, fallback to /tmp if it is usable.
  #
  if {$::tcl_platform(platform) ne "windows"} {
    set value /tmp

    if {[file exists $value] && [file isdirectory $value]} then {
      return $value
    }
  }

  #
  # NOTE: There must be a usable temporary directory to continue testing.
  #
................................................................................
        set line [string range $line 0 $i]$stuff[string range $line $ip1 end]
      }
    }
    append out \n$line
  }
  return [string range $out 1 end]
}











































































# Executes the "fossil http" command.  The entire content of the HTTP request
# is read from the data file name, with [subst] being performed on it prior to
# submission.  Temporary input and output files are created and deleted.  The
# result will be the contents of the temoprary output file.
proc test_fossil_http { repository dataFileName url } {
  set suffix [appendArgs [pid] - [getSeqNo] - [clock seconds] .txt]







|
>

<
>
>
>
>
>
>
>











>
>
>
|
>


>
>
>
|
>







 







|







 







|





|





|





|







 







|

|

|







|

|

|







 







|


|











|







 







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







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
...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
...
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
...
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
...
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
...
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
# Sets the CODE and RESULT global variables for use in
# test expressions.
#
proc fossil_maybe_answer {answer args} {
  global fossilexe
  set cmd $fossilexe
  set expectError 0
  set index [lsearch -exact $args -expectError]
  if {$index != -1} {
    set expectError 1

    set args [lreplace $args $index $index]
  }
  set keepNewline 0
  set index [lsearch -exact $args -keepNewline]
  if {$index != -1} {
    set keepNewline 1
    set args [lreplace $args $index $index]
  }
  foreach a $args {
    lappend cmd $a
  }
  protOut $cmd

  flush stdout
  if {[string length $answer] > 0} {
    protOut $answer
    set prompt_file [file join $::tempPath fossil_prompt_answer]
    write_file $prompt_file $answer\n
    if {$keepNewline} {
      set rc [catch {eval exec -keepnewline $cmd <$prompt_file} result]
    } else {
      set rc [catch {eval exec $cmd <$prompt_file} result]
    }
    file delete $prompt_file
  } else {
    if {$keepNewline} {
      set rc [catch {eval exec -keepnewline $cmd} result]
    } else {
      set rc [catch {eval exec $cmd} result]
    }
  }
  global RESULT CODE
  set CODE $rc
  if {($rc && !$expectError) || (!$rc && $expectError)} {
    protOut "ERROR: $result" 1
  } elseif {$::VERBOSE} {
    protOut "RESULT: $result"
................................................................................
      keep-glob \
      manifest \
      th1-setup \
      th1-uri-regexp]

  fossil test-th-eval "hasfeature tcl"

  if {[normalize_result] eq "1"} {
    lappend result tcl-setup
  }

  return [lsort -dictionary $result]
}

# Returns the list of all supported settings.
................................................................................
      th1-setup \
      th1-uri-regexp \
      uv-sync \
      web-browser]

  fossil test-th-eval "hasfeature legacyMvRm"

  if {[normalize_result] eq "1"} {
    lappend result mv-rm-files
  }

  fossil test-th-eval "hasfeature tcl"

  if {[normalize_result] eq "1"} {
    lappend result tcl tcl-setup
  }

  fossil test-th-eval "hasfeature th1Docs"

  if {[normalize_result] eq "1"} {
    lappend result th1-docs
  }

  fossil test-th-eval "hasfeature th1Hooks"

  if {[normalize_result] eq "1"} {
    lappend result th1-hooks
  }

  return [lsort -dictionary $result]
}

# Return true if two files are the same
................................................................................
  }
}

# This procedure only returns non-zero if the Tcl integration feature was
# enabled at compile-time and is now enabled at runtime.
proc is_tcl_usable_by_fossil {} {
  fossil test-th-eval "hasfeature tcl"
  if {[normalize_result] ne "1"} {return 0}
  fossil test-th-eval "setting tcl"
  if {[normalize_result] eq "1"} {return 1}
  fossil test-th-eval --open-config "setting tcl"
  if {[normalize_result] eq "1"} {return 1}
  return [info exists ::env(TH1_ENABLE_TCL)]
}

# This procedure only returns non-zero if the TH1 hooks feature was enabled
# at compile-time and is now enabled at runtime.
proc are_th1_hooks_usable_by_fossil {} {
  fossil test-th-eval "hasfeature th1Hooks"
  if {[normalize_result] ne "1"} {return 0}
  fossil test-th-eval "setting th1-hooks"
  if {[normalize_result] eq "1"} {return 1}
  fossil test-th-eval --open-config "setting th1-hooks"
  if {[normalize_result] eq "1"} {return 1}
  return [info exists ::env(TH1_ENABLE_HOOKS)]
}

# This (rarely used) procedure is designed to run a test within the Fossil
# source checkout (e.g. one that does NOT modify any state), while saving
# and restoring the current directory (e.g. one used when running a test
# file outside of the Fossil source checkout).  Please do NOT use this
................................................................................

  #
  # NOTE: Check if we can use any of the environment variables.
  #
  foreach name $names {
    set value [getEnvironmentVariable $name]

    if {[string length $value] > 0} {
      set value [file normalize $value]

      if {[file exists $value] && [file isdirectory $value]} {
        return $value
      }
    }
  }

  #
  # NOTE: On non-Windows systems, fallback to /tmp if it is usable.
  #
  if {$::tcl_platform(platform) ne "windows"} {
    set value /tmp

    if {[file exists $value] && [file isdirectory $value]} {
      return $value
    }
  }

  #
  # NOTE: There must be a usable temporary directory to continue testing.
  #
................................................................................
        set line [string range $line 0 $i]$stuff[string range $line $ip1 end]
      }
    }
    append out \n$line
  }
  return [string range $out 1 end]
}

# This procedure executes the "fossil server" command.  The return value
# is the new process identifier.  The varName argument refers to a variable
# where the "stop argument" is to be stored.  This value must eventually be
# passed to the [test_stop_server] procedure.
proc test_start_server { repository {varName ""} } {
  global fossilexe
  set command [list exec $fossilexe server]
  if {[string length $varName] > 0} {
    upvar 1 $varName stopArg
  }
  if {$::tcl_platform(platform) eq "windows"} {
    set stopArg [file join [getTemporaryPath] [appendArgs \
        [string trim [clock seconds] -] _ [getSeqNo] .stopper]]
    lappend command --stopper $stopArg
  }
  lappend command $repository &
  set pid [eval $command]
  if {$::tcl_platform(platform) ne "windows"} {
    set stopArg $pid
  }
  return $pid
}

# This procedure stops a Fossil server instance that was previously started
# by the [test_start_server] procedure.  The value of the "stop argument"
# will vary by platform as will the exact method used to stop the server.
proc test_stop_server { stopArg pid } {
  if {$::tcl_platform(platform) eq "windows"} {
    #
    # NOTE: On Windows, the "stop argument" must be the name of a file
    #       that does NOT already exist.
    #
    if {![file exists $stopArg] && \
        [catch {write_file $stopArg [clock seconds]}] == 0} then {
      while {1} {
        if {[catch {
          #
          # NOTE: Using the TaskList utility requires Windows XP or
          #       later.
          #
          exec tasklist.exe /FI "PID eq $pid"
        } result] != 0 || ![regexp -- " $pid " $result]} then {
          break
        }
        after 1000; # wait a bit...
      }
      file delete $stopArg
      return true
    }
  } else {
    #
    # NOTE: On Unix, the "stop argument" must be an integer identifier
    #       that refers to an existing process.
    #
    if {[regexp {^(?:-)?\d+$} $stopArg] && \
        [catch {exec kill -TERM $stopArg}] == 0} then {
      while {1} {
        if {[catch {
          #
          # TODO: Is this portable to all the supported variants of
          #       Unix?  It should be, it's POSIX.
          #
          exec ps -p $pid
        } result] != 0 || ![regexp -- "(?:^$pid| $pid) " $result]} then {
          break
        }
        after 1000; # wait a bit...
      }
      return true
    }
  }
  return false
}

# Executes the "fossil http" command.  The entire content of the HTTP request
# is read from the data file name, with [subst] being performed on it prior to
# submission.  Temporary input and output files are created and deleted.  The
# result will be the contents of the temoprary output file.
proc test_fossil_http { repository dataFileName url } {
  set suffix [appendArgs [pid] - [getSeqNo] - [clock seconds] .txt]

Changes to test/th1-docs.test.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
############################################################################
#
# TH1 Docs
#

fossil test-th-eval "hasfeature th1Docs"

if {$::RESULT ne "1"} {
  puts "Fossil was not compiled with TH1 docs support."
  test_cleanup_then_return
}

fossil test-th-eval "hasfeature tcl"

if {$::RESULT ne "1"} {
  puts "Fossil was not compiled with Tcl support."
  test_cleanup_then_return
}

###############################################################################

test_setup ""







|






|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
############################################################################
#
# TH1 Docs
#

fossil test-th-eval "hasfeature th1Docs"

if {[normalize_result] ne "1"} {
  puts "Fossil was not compiled with TH1 docs support."
  test_cleanup_then_return
}

fossil test-th-eval "hasfeature tcl"

if {[normalize_result] ne "1"} {
  puts "Fossil was not compiled with Tcl support."
  test_cleanup_then_return
}

###############################################################################

test_setup ""

Changes to test/th1-hooks.test.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
73
74
75
76
77
78
79

80
81




82
83
84
85
86
87
88
...
120
121
122
123
124
125
126
127
128
129
130
131






132
133
134
135
136
137
138
############################################################################
#
# TH1 Hooks
#

fossil test-th-eval "hasfeature th1Hooks"

if {$::RESULT ne "1"} {
  puts "Fossil was not compiled with TH1 hooks support."
  test_cleanup_then_return
}

###############################################################################

test_setup
................................................................................
    } elseif {$::cmd_name eq "test4"} {
      emit_hook_log
      return -code 2 "TH_RETURN return code"
    } elseif {$::cmd_name eq "timeline"} {
      set length [llength $::cmd_args]
      set length [expr {$length - 1}]
      if {[lindex $::cmd_args $length] eq "custom"} {

        emit_hook_log
        return "custom timeline"




      } elseif {[lindex $::cmd_args $length] eq "now"} {
        emit_hook_log
        return "now timeline"
      } else {
        emit_hook_log
        error "unsupported timeline"
      }
................................................................................

###############################################################################

saveTh1SetupFile; writeTh1SetupFile $testTh1Setup

###############################################################################

fossil timeline custom; # NOTE: Bad "WHEN" argument.
test th1-cmd-hooks-1a {[normalize_result] eq \
{<h1><b>command_hook timeline</b></h1>
+++ no more data (0) +++







<h1><b>command_hook timeline command_notify timeline</b></h1>}}

###############################################################################

fossil timeline
test th1-cmd-hooks-2a {[first_data_line] eq \
    {<h1><b>command_hook timeline</b></h1>}}







|







 







>


>
>
>
>







 







|

|
|

>
>
>
>
>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
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
############################################################################
#
# TH1 Hooks
#

fossil test-th-eval "hasfeature th1Hooks"

if {[normalize_result] ne "1"} {
  puts "Fossil was not compiled with TH1 hooks support."
  test_cleanup_then_return
}

###############################################################################

test_setup
................................................................................
    } elseif {$::cmd_name eq "test4"} {
      emit_hook_log
      return -code 2 "TH_RETURN return code"
    } elseif {$::cmd_name eq "timeline"} {
      set length [llength $::cmd_args]
      set length [expr {$length - 1}]
      if {[lindex $::cmd_args $length] eq "custom"} {
        append_hook_log "CUSTOM TIMELINE"
        emit_hook_log
        return "custom timeline"
      } elseif {[lindex $::cmd_args $length] eq "custom2"} {
        emit_hook_log
        puts "+++ some stuff here +++"
        continue "custom2 timeline"
      } elseif {[lindex $::cmd_args $length] eq "now"} {
        emit_hook_log
        return "now timeline"
      } else {
        emit_hook_log
        error "unsupported timeline"
      }
................................................................................

###############################################################################

saveTh1SetupFile; writeTh1SetupFile $testTh1Setup

###############################################################################

fossil timeline custom -expectError; # NOTE: Bad "WHEN" argument.
test th1-cmd-hooks-1a {[normalize_result] eq \
{<h1><b>command_hook timeline CUSTOM TIMELINE</b></h1>
unknown check-in or invalid date: custom}}

###############################################################################

fossil timeline custom2; # NOTE: Bad "WHEN" argument.
test th1-cmd-hooks-1b {[normalize_result] eq \
{<h1><b>command_hook timeline</b></h1>
+++ some stuff here +++
<h1><b>command_hook timeline command_notify timeline</b></h1>}}

###############################################################################

fossil timeline
test th1-cmd-hooks-2a {[first_data_line] eq \
    {<h1><b>command_hook timeline</b></h1>}}

Changes to test/th1-repo.test.

17
18
19
20
21
22
23


24
25
26
27
28
29
30
..
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#   Chris Drexler <ckolumbus@ac-drexler.de>
#
############################################################################
#
# TH1 tests that may modify the repository
#



require_no_open_checkout

########################################
# Setup: Add Files and Commit          #
########################################

test_setup; set rootDir [file normalize [pwd]]
................................................................................
write_file [file join $rootDir subdirC f11t.xt] "f11"

set files_md [list subdirB/f5.md subdirB/f6.md subdirB/f8.md subdirC/f10.md]

fossil add $rootDir
fossil commit -m "c1"

set dir [file dirname [info script]]

###############################################################################

fossil test-th-eval --open-config "dir trunk subdir*/*.md"
test th1-dir-1 {[llength $RESULT] eq [llength $files_md]}

set n 1
foreach i $RESULT j $files_md {







>
>







 







<
<







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
51
52
53
54
55
56
57


58
59
60
61
62
63
64
#   Chris Drexler <ckolumbus@ac-drexler.de>
#
############################################################################
#
# TH1 tests that may modify the repository
#

set path [file dirname [info script]]

require_no_open_checkout

########################################
# Setup: Add Files and Commit          #
########################################

test_setup; set rootDir [file normalize [pwd]]
................................................................................
write_file [file join $rootDir subdirC f11t.xt] "f11"

set files_md [list subdirB/f5.md subdirB/f6.md subdirB/f8.md subdirC/f10.md]

fossil add $rootDir
fossil commit -m "c1"



###############################################################################

fossil test-th-eval --open-config "dir trunk subdir*/*.md"
test th1-dir-1 {[llength $RESULT] eq [llength $files_md]}

set n 1
foreach i $RESULT j $files_md {

Changes to test/th1-tcl.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
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
#   http://www.hwaci.com/drh/
#
############################################################################
#
# TH1/Tcl integration
#

set dir [file dirname [info script]]

###############################################################################

fossil test-th-eval "hasfeature tcl"

if {$::RESULT ne "1"} {
  puts "Fossil was not compiled with Tcl support."
  test_cleanup_then_return
}

###############################################################################

test_setup
................................................................................
###############################################################################

set env(TH1_ENABLE_TCL) 1; # Tcl integration must be enabled for this test.

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl1.txt]]

test th1-tcl-1 {[regexp -- {^tclReady\(before\) = 0
tclReady\(after\) = 1
\d+
\d+
\d+
via Tcl invoke
................................................................................
one_word
three words now$} [normalize_result]]}

###############################################################################

if {[catch {package require sqlite3}] == 0} {
  fossil test-th-render --open-config \
      [file nativename [file join $dir th1-tcl2.txt]]

  test th1-tcl-2 {[regexp -- {^\d+$} [normalize_result]]}
} else {
  puts stderr "Skipping 'th1-tcl-2', SQLite package for Tcl not available"
}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl3.txt]]

test th1-tcl-3 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl4.txt]]

test th1-tcl-4 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
divide by zero</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl5.txt]]

test th1-tcl-5 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
Tcl command not found: bad_command</p>} || $RESULT eq {<hr /><p\
class="thmainError">ERROR: invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl6.txt]]

test th1-tcl-6 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
no such command:  bad_command</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl7.txt]]

test th1-tcl-7 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
syntax error in expression: &quot;2**0&quot;</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl8.txt]]

test th1-tcl-8 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
cannot invoke Tcl command: tailcall</p>} || $RESULT eq {<hr /><p\
class="thmainError">ERROR: tailcall can only be called from a proc or\
lambda</p>} || $RESULT eq {<hr /><p class="thmainError">ERROR: This test\
requires Tcl 8.6 or higher.</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $dir th1-tcl9.txt]]

test th1-tcl-9 {[string trim $RESULT] eq [list [file tail $fossilexe] 3 \
[list test-th-render --open-config [file nativename [file join $dir \
th1-tcl9.txt]]]]}

###############################################################################

fossil test-th-eval "tclMakeSafe a"
test th1-tcl-10 {[normalize_result] eq \
{TH_ERROR: wrong # args: should be "tclMakeSafe"}}







|





|







 







|







 







|









|







|







|








|







|







|










|


|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
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
#   http://www.hwaci.com/drh/
#
############################################################################
#
# TH1/Tcl integration
#

set path [file dirname [info script]]

###############################################################################

fossil test-th-eval "hasfeature tcl"

if {[normalize_result] ne "1"} {
  puts "Fossil was not compiled with Tcl support."
  test_cleanup_then_return
}

###############################################################################

test_setup
................................................................................
###############################################################################

set env(TH1_ENABLE_TCL) 1; # Tcl integration must be enabled for this test.

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl1.txt]]

test th1-tcl-1 {[regexp -- {^tclReady\(before\) = 0
tclReady\(after\) = 1
\d+
\d+
\d+
via Tcl invoke
................................................................................
one_word
three words now$} [normalize_result]]}

###############################################################################

if {[catch {package require sqlite3}] == 0} {
  fossil test-th-render --open-config \
      [file nativename [file join $path th1-tcl2.txt]]

  test th1-tcl-2 {[regexp -- {^\d+$} [normalize_result]]}
} else {
  puts stderr "Skipping 'th1-tcl-2', SQLite package for Tcl not available"
}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl3.txt]]

test th1-tcl-3 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl4.txt]]

test th1-tcl-4 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
divide by zero</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl5.txt]]

test th1-tcl-5 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
Tcl command not found: bad_command</p>} || $RESULT eq {<hr /><p\
class="thmainError">ERROR: invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl6.txt]]

test th1-tcl-6 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
no such command:  bad_command</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl7.txt]]

test th1-tcl-7 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
syntax error in expression: &quot;2**0&quot;</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl8.txt]]

test th1-tcl-8 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
cannot invoke Tcl command: tailcall</p>} || $RESULT eq {<hr /><p\
class="thmainError">ERROR: tailcall can only be called from a proc or\
lambda</p>} || $RESULT eq {<hr /><p class="thmainError">ERROR: This test\
requires Tcl 8.6 or higher.</p>}}

###############################################################################

fossil test-th-render --open-config \
    [file nativename [file join $path th1-tcl9.txt]]

test th1-tcl-9 {[string trim $RESULT] eq [list [file tail $fossilexe] 3 \
[list test-th-render --open-config [file nativename [file join $path \
th1-tcl9.txt]]]]}

###############################################################################

fossil test-th-eval "tclMakeSafe a"
test th1-tcl-10 {[normalize_result] eq \
{TH_ERROR: wrong # args: should be "tclMakeSafe"}}

Changes to test/th1.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
#   http://www.hwaci.com/drh/
#
############################################################################
#
# TH1 Commands
#

set dir [file dirname [info script]]; test_setup

###############################################################################

set th1Tcl [is_tcl_usable_by_fossil]
set th1Hooks [are_th1_hooks_usable_by_fossil]

###############################################################################
................................................................................
<p><em>This is a test.</em></p>

</div>
}}}

###############################################################################

set markdown [read_file [file join $dir markdown-test1.md]]
fossil test-th-eval [string map \
    [list %markdown% $markdown] {markdown {%markdown%}}]
test th1-markdown-5 {[normalize_result] eq \
{{Markdown Formatter Test Document} {<div class="markdown">

<p>This document is designed to test the markdown formatter.</p>








|







 







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
#   http://www.hwaci.com/drh/
#
############################################################################
#
# TH1 Commands
#

set path [file dirname [info script]]; test_setup

###############################################################################

set th1Tcl [is_tcl_usable_by_fossil]
set th1Hooks [are_th1_hooks_usable_by_fossil]

###############################################################################
................................................................................
<p><em>This is a test.</em></p>

</div>
}}}

###############################################################################

set markdown [read_file [file join $path markdown-test1.md]]
fossil test-th-eval [string map \
    [list %markdown% $markdown] {markdown {%markdown%}}]
test th1-markdown-5 {[normalize_result] eq \
{{Markdown Formatter Test Document} {<div class="markdown">

<p>This document is designed to test the markdown formatter.</p>

Added test/unversioned.test.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#
# Copyright (c) 2016 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/
#
############################################################################
#
# The "unversioned" command.
#

set path [file dirname [info script]]

if {[catch {package require sha1}] != 0} then {
  puts "The \"sha1\" package is not available."
  test_cleanup_then_return
}

require_no_open_checkout

test_setup; set rootDir [file normalize [pwd]]

fossil test-th-eval --open-config {repository}
set repository [normalize_result]

if {[string length $repository] == 0} {
  puts "Detection of the open repository file failed."
  test_cleanup_then_return
}

write_file unversioned1.txt "This is unversioned file #1."
write_file unversioned2.txt " This is unversioned file #2. "
write_file "unversioned space.txt" "\nThis is unversioned file #3.\n"
write_file unversioned4.txt "This is unversioned file #4."
write_file unversioned5.txt "This is unversioned file #5."

set env(VISUAL) [appendArgs \
    [info nameofexecutable] " " [file join $path fake-editor.tcl]]

###############################################################################

fossil unversioned
test unversioned-1 {[normalize_result] eq \
[string map [list %fossil% [file nativename $fossilexe]] {Usage: %fossil%\
unversioned add|cat|edit|export|list|revert|remove|sync|touch}]}

###############################################################################

fossil unversioned list
test unversioned-2 {[normalize_result] eq {}}

###############################################################################

fossil unversioned cat not-found.txt
test unversioned-3 {[normalize_result] eq {}}

###############################################################################

fossil unversioned cat unversioned1.txt
test unversioned-4 {[normalize_result] eq {}}

###############################################################################

fossil unversioned add unversioned1.txt
test unversioned-5 {[normalize_result] eq {}}

###############################################################################

fossil unversioned cat unversioned1.txt
test unversioned-6 {[normalize_result] eq {This is unversioned file #1.}}

###############################################################################

fossil unversioned list
test unversioned-7 {[regexp \
{^[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       28       28\
unversioned1\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned ls
test unversioned-8 {[normalize_result] eq {unversioned1.txt}}

###############################################################################

fossil unversioned remove unversioned1.txt
test unversioned-9 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list
test unversioned-10 {[normalize_result] eq {}}

###############################################################################

fossil unversioned ls
test unversioned-11 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list --all
test unversioned-12 {[regexp \
{^\(deleted\) \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}        0        0\
unversioned1\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned ls --all
test unversioned-13 {[normalize_result] eq {unversioned1.txt}}

###############################################################################

fossil unversioned add "unversioned space.txt" -expectError
test unversioned-14 {[normalize_result] eq \
{names of unversioned files may not contain whitespace}}

###############################################################################

fossil unversioned add "unversioned space.txt" --as unversioned3.txt
test unversioned-15 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list
test unversioned-16 {[regexp \
{^[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       30       30\
unversioned3\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned ls --l
test unversioned-17 {[regexp \
{^[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       30       30\
unversioned3\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned ls
test unversioned-18 {[normalize_result] eq {unversioned3.txt}}

###############################################################################

fossil unversioned add unversioned2.txt --mtime 2016-10-01
test unversioned-19 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list
test unversioned-20 {[regexp \
{^[0-9a-f]{12} 2016-10-01 00:00:00       30       30\
unversioned2\.txt
[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       30       30\
unversioned3\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned ls
test unversioned-21 {[normalize_result] eq {unversioned2.txt
unversioned3.txt}}

###############################################################################

fossil unversioned cat unversioned1.txt
test unversioned-22 {[normalize_result] eq {}}

###############################################################################

fossil unversioned cat unversioned2.txt
test unversioned-23 {[::sha1::sha1 $RESULT] eq \
{962f96ebd613e4fdd9aa2d20bd9fe21a64e925f2}}

###############################################################################

fossil unversioned cat unversioned3.txt -keepNewline
test unversioned-24 {[::sha1::sha1 $RESULT] eq \
{c6b95509120d9703cc4fbe5cdfcb435b5912b3e4}}

###############################################################################

fossil unversioned rm unversioned3.txt
test unversioned-25 {[normalize_result] eq {}}

###############################################################################

fossil unversioned add unversioned4.txt
test unversioned-26 {[normalize_result] eq {}}

###############################################################################

fossil unversioned cat unversioned4.txt
set hash(before) [::sha1::sha1 $RESULT]
test unversioned-27 {$hash(before) eq \
{b48ba8e2d0b498321dfd13de84867effda399af5}}

###############################################################################

fossil unversioned edit unversioned4.txt
test unversioned-28 {[normalize_result] eq {}}

###############################################################################

fossil unversioned cat unversioned4.txt
set hash(after) [::sha1::sha1 $RESULT]
test unversioned-29 {$hash(after) ne $hash(before)}
test unversioned-30 {[regexp { \d+ (?:-)?\d+$} $RESULT]}

###############################################################################

fossil unversioned edit unversioned4.txt --mtime 2016-10-01
test unversioned-31 {[normalize_result] eq {}}

###############################################################################

fossil unversioned cat unversioned4.txt
test unversioned-32 {[regexp { \d+ (?:-)?\d+ \d+ (?:-)?\d+$} $RESULT]}

###############################################################################

fossil unversioned list
test unversioned-33 {[regexp \
{^[0-9a-f]{12} 2016-10-01 00:00:00       30       30\
unversioned2\.txt
[0-9a-f]{12} 2016-10-01 00:00:00       \d+       \d+\
unversioned4\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned export unversioned2.txt unversioned2-ex.txt
test unversioned-34 {[normalize_result] eq {}}
test unversioned-35 {[::sha1::sha1 -hex -filename unversioned2-ex.txt] eq \
{962f96ebd613e4fdd9aa2d20bd9fe21a64e925f2}}

###############################################################################

fossil unversioned hash
test unversioned-36 {[regexp {^[0-9a-f]{40}$} [normalize_result]]}

###############################################################################

fossil unversioned hash --debug
test unversioned-37 {[regexp \
{^unversioned2\.txt 2016-10-01 00:00:00 [0-9a-f]{40}
unversioned4\.txt 2016-10-01 00:00:00 [0-9a-f]{40}
[0-9a-f]{40}$} [normalize_result]]}

###############################################################################

fossil unversioned remove unversioned4.txt --mtime "2016-10-02 13:47:29"
test unversioned-38 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list --all
test unversioned-39 {[regexp \
{^\(deleted\) \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}        0        0\
unversioned1\.txt
[0-9a-f]{12} 2016-10-01 00:00:00       30       30 unversioned2\.txt
   \(deleted\) \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}        0        0\
unversioned3\.txt
   \(deleted\) 2016-10-02 13:47:29        0        0 unversioned4\.txt$} \
[normalize_result]]}

###############################################################################

fossil unversioned touch unversioned1.txt --mtime "2016-10-03 23:01:44"
test unversioned-40 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list --all
test unversioned-41 {[regexp \
{^\(deleted\) 2016-10-03 23:01:44        0        0\
unversioned1\.txt
[0-9a-f]{12} 2016-10-01 00:00:00       30       30 unversioned2\.txt
   \(deleted\) \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}        0        0\
unversioned3\.txt
   \(deleted\) 2016-10-02 13:47:29        0        0 unversioned4\.txt$} \
[normalize_result]]}

###############################################################################

fossil unversioned add unversioned5.txt
test unversioned-42 {[normalize_result] eq {}}

###############################################################################

fossil unversioned touch unversioned5.txt
test unversioned-43 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list
test unversioned-44 {[regexp \
{^[0-9a-f]{12} 2016-10-01 00:00:00       30       30 unversioned2\.txt
[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       28       28\
unversioned5\.txt$} [normalize_result]]}

###############################################################################

set password [string trim [clock seconds] -]
set remote [appendArgs http://uvtester: $password @localhost:8080/]

fossil user new uvtester "Unversioned Test User" $password
fossil user capabilities uvtester oy

###############################################################################

set pid [test_start_server $repository stopArg]
puts [appendArgs "Started Fossil server, pid \"" $pid \".]

###############################################################################

set clientDir [file join $tempPath [appendArgs \
    uvtest_ [string trim [clock seconds] -] _ [getSeqNo]]]

set savedPwd [pwd]
file mkdir $clientDir; cd $clientDir
puts [appendArgs "Now in client directory \"" [pwd] \".]
write_file unversioned-client1.txt "This is unversioned client file #1."

###############################################################################

fossil_maybe_answer y clone $remote uvrepo.fossil
fossil open uvrepo.fossil

###############################################################################

fossil unversioned list
test unversioned-45 {[normalize_result] eq {}}

###############################################################################

fossil_maybe_answer y unversioned sync $remote
test unversioned-46 {[regexp \
{Round-trips: 1   Artifacts sent: 0  received: 0
Round-trips: 1   Artifacts sent: 0  received: 0
Round-trips: 2   Artifacts sent: 0  received: 0
Round-trips: 2   Artifacts sent: 0  received: 2
\n? done, sent: \d+  received: \d+  ip: 127.0.0.1} [normalize_result]]}

###############################################################################

fossil unversioned ls
test unversioned-47 {[normalize_result] eq {unversioned2.txt
unversioned5.txt}}

###############################################################################

set env(FAKE_EDITOR_SCRIPT) "append data this_is_a_test"; # deterministic

fossil unversioned edit unversioned2.txt
test unversioned-48 {[normalize_result] eq {}}

unset env(FAKE_EDITOR_SCRIPT)

###############################################################################

fossil unversioned cat unversioned2.txt
test unversioned-49 {[::sha1::sha1 $RESULT] eq \
{e15d4b576fc04e3bb5e44a33d44d104dd5b19428}}

###############################################################################

fossil unversioned remove unversioned5.txt
test unversioned-50 {[normalize_result] eq {}}

###############################################################################

fossil unversioned list --all
test unversioned-51 {[regexp \
{^[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       44       44\
unversioned2\.txt
   \(deleted\) \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}        0        0\
unversioned5\.txt$} [normalize_result]]}

###############################################################################

fossil_maybe_answer y unversioned revert $remote
test unversioned-52 {[regexp \
{Round-trips: 1   Artifacts sent: 0  received: 0
Round-trips: 1   Artifacts sent: 0  received: 0
Round-trips: 2   Artifacts sent: 0  received: 0
Round-trips: 2   Artifacts sent: 0  received: 2
\n? done, sent: \d+  received: \d+  ip: 127.0.0.1} [normalize_result]]}

###############################################################################

fossil unversioned list
test unversioned-53 {[regexp \
{^[0-9a-f]{12} 2016-10-01 00:00:00       30       30\
unversioned2\.txt
[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       28       28\
unversioned5\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned add unversioned-client1.txt
test unversioned-54 {[normalize_result] eq {}}

###############################################################################

fossil_maybe_answer y unversioned sync $remote
test unversioned-55 {[regexp \
{Round-trips: 1   Artifacts sent: 0  received: 0
Round-trips: 1   Artifacts sent: 0  received: 0
Round-trips: 2   Artifacts sent: 1  received: 0
Round-trips: 2   Artifacts sent: 1  received: 0
\n? done, sent: \d+  received: \d+  ip: 127.0.0.1} [normalize_result]]}

###############################################################################

fossil close
test unversioned-56 {[normalize_result] eq {}}

###############################################################################

cd $savedPwd; unset savedPwd
file delete -force $clientDir
puts [appendArgs "Now in server directory \"" [pwd] \".]

###############################################################################

set stopped [test_stop_server $stopArg $pid]

puts [appendArgs \
    [expr {$stopped ? "Stopped" : "Could not stop"}] \
    " Fossil server, pid \"" $pid "\", using argument \"" \
    $stopArg \".]

###############################################################################

fossil unversioned list
test unversioned-57 {[regexp \
{^[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       35       35\
unversioned-client1\.txt
[0-9a-f]{12} 2016-10-01 00:00:00       30       30 unversioned2\.txt
[0-9a-f]{12} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}       28       28\
unversioned5\.txt$} [normalize_result]]}

###############################################################################

fossil unversioned cat unversioned-client1.txt
test unversioned-58 {[::sha1::sha1 $RESULT] eq \
{a34606f714afe309bb531fba6051eaf25201e8a2}}

###############################################################################

test_cleanup

Changes to win/Makefile.PellesCGMake.

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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))
SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_WIN32_NO_ANSI

# define the SQLite shell files, which need special flags on compile
SQLITESHELLSRC=shell.c
ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
SQLITESHELLDEFINES=-Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -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








|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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))
SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_WIN32_NO_ANSI

# define the SQLite shell files, which need special flags on compile
SQLITESHELLSRC=shell.c
ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
SQLITESHELLDEFINES=-Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -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

Changes to win/Makefile.dmc.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SSL    =

CFLAGS = -o
BCC    = $(DMDIR)\bin\dmc $(CFLAGS)
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -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 bundle_.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 dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.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 piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.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)\bundle$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)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fshell$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)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$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)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$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)\unversioned$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 








|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SSL    =

CFLAGS = -o
BCC    = $(DMDIR)\bin\dmc $(CFLAGS)
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -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 bundle_.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 dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.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 piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.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)\bundle$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)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fshell$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)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$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)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$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)\unversioned$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 

Changes to win/Makefile.mingw.

2172
2173
2174
2175
2176
2177
2178


2179
2180
2181
2182
2183
2184
2185
                 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 -DSQLITE_OMIT_DECLTYPE \
                 -DSQLITE_OMIT_DEPRECATED \
                 -DSQLITE_OMIT_PROGRESS_CALLBACK \
                 -DSQLITE_OMIT_SHARED_CACHE \
                 -DSQLITE_OMIT_LOAD_EXTENSION \


                 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 -DSQLITE_ENABLE_FTS4 \
                 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_JSON1 \







>
>







2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
                 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 -DSQLITE_OMIT_DECLTYPE \
                 -DSQLITE_OMIT_DEPRECATED \
                 -DSQLITE_OMIT_PROGRESS_CALLBACK \
                 -DSQLITE_OMIT_SHARED_CACHE \
                 -DSQLITE_OMIT_LOAD_EXTENSION \
                 -DSQLITE_MAX_EXPR_DEPTH=0 \
                 -DSQLITE_USE_ALLOCA \
                 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 -DSQLITE_ENABLE_FTS4 \
                 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_JSON1 \

Changes to win/Makefile.mingw.mistachkin.

2172
2173
2174
2175
2176
2177
2178


2179
2180
2181
2182
2183
2184
2185
                 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 -DSQLITE_OMIT_DECLTYPE \
                 -DSQLITE_OMIT_DEPRECATED \
                 -DSQLITE_OMIT_PROGRESS_CALLBACK \
                 -DSQLITE_OMIT_SHARED_CACHE \
                 -DSQLITE_OMIT_LOAD_EXTENSION \


                 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 -DSQLITE_ENABLE_FTS4 \
                 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_JSON1 \







>
>







2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
                 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 -DSQLITE_OMIT_DECLTYPE \
                 -DSQLITE_OMIT_DEPRECATED \
                 -DSQLITE_OMIT_PROGRESS_CALLBACK \
                 -DSQLITE_OMIT_SHARED_CACHE \
                 -DSQLITE_OMIT_LOAD_EXTENSION \
                 -DSQLITE_MAX_EXPR_DEPTH=0 \
                 -DSQLITE_USE_ALLOCA \
                 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 -DSQLITE_ENABLE_FTS4 \
                 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_JSON1 \

Changes to win/Makefile.msc.

319
320
321
322
323
324
325


326
327
328
329
330
331
332
                 /DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 /DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 /DSQLITE_OMIT_DECLTYPE \
                 /DSQLITE_OMIT_DEPRECATED \
                 /DSQLITE_OMIT_PROGRESS_CALLBACK \
                 /DSQLITE_OMIT_SHARED_CACHE \
                 /DSQLITE_OMIT_LOAD_EXTENSION \


                 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 /DSQLITE_ENABLE_FTS4 \
                 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 /DSQLITE_ENABLE_DBSTAT_VTAB \
                 /DSQLITE_ENABLE_JSON1 \







>
>







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
                 /DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
                 /DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
                 /DSQLITE_OMIT_DECLTYPE \
                 /DSQLITE_OMIT_DEPRECATED \
                 /DSQLITE_OMIT_PROGRESS_CALLBACK \
                 /DSQLITE_OMIT_SHARED_CACHE \
                 /DSQLITE_OMIT_LOAD_EXTENSION \
                 /DSQLITE_MAX_EXPR_DEPTH=0 \
                 /DSQLITE_USE_ALLOCA \
                 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
                 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
                 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
                 /DSQLITE_ENABLE_FTS4 \
                 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
                 /DSQLITE_ENABLE_DBSTAT_VTAB \
                 /DSQLITE_ENABLE_JSON1 \

Changes to www/aboutcgi.wiki.

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
exactly the same thing to Fossil:
<ol type='A'>
<li> [https://www.fossil-scm.org/fossil/info/c14ecc43]
<li> [https://www.fossil-scm.org/fossil/info?name=c14ecc43]
</ol>
In both cases, the CGI script is called "/fossil".  For case (A),
the PATH_INFO variable will be "info/c14ecc43" and so the 
"[/help?cmd=/info]" webpage will be generated and the suffix of
PATH_INFO will be converted into the "name" query parameter, which
identifies the artifact about which information is requested.
In case (B), the PATH_INFO is just "info", but the same "name"
query parameter is set explicitly by the URL itself.
</blockquote>
<h2>Serving Multiple Fossil Repositories From One CGI Script</h2>
<blockquote>







|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
exactly the same thing to Fossil:
<ol type='A'>
<li> [https://www.fossil-scm.org/fossil/info/c14ecc43]
<li> [https://www.fossil-scm.org/fossil/info?name=c14ecc43]
</ol>
In both cases, the CGI script is called "/fossil".  For case (A),
the PATH_INFO variable will be "info/c14ecc43" and so the 
"[/help?cmd=/info|/info]" webpage will be generated and the suffix of
PATH_INFO will be converted into the "name" query parameter, which
identifies the artifact about which information is requested.
In case (B), the PATH_INFO is just "info", but the same "name"
query parameter is set explicitly by the URL itself.
</blockquote>
<h2>Serving Multiple Fossil Repositories From One CGI Script</h2>
<blockquote>

Changes to www/changes.wiki.

6
7
8
9
10
11
12



13
14
15
16
17
18
19
     the [/help?cmd=unversioned|fossil unversioned] command and the
     [/help?cmd=/uv|/uv] and [/uvlist] web pages.
  *  The [/uv/download.html|download page] is moved into
     [./unvers.wiki|unversioned content] so that the self-hosting Fossil
     websites no longer uses any external content.
  *  Added the "Search" button to the graphical diff generated by
     the --tk option on the [/help?cmd=diff|diff] command.



  *  Update internal Unicode character tables, used in regular expression
     handling, from version 8.0 to 9.0.
  *  Update the built-in SQLite to version 3.15 (beta). Fossil now requires
     the SQLITE_DBCONFIG_MAINDBNAME interface of SQLite which is only available
     in SQLite version 3.15 and later and so Fossil will not work with
     earlier SQLite versions.
  *  Fix [https://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg23618.html|multi-line timeline bug]







>
>
>







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     the [/help?cmd=unversioned|fossil unversioned] command and the
     [/help?cmd=/uv|/uv] and [/uvlist] web pages.
  *  The [/uv/download.html|download page] is moved into
     [./unvers.wiki|unversioned content] so that the self-hosting Fossil
     websites no longer uses any external content.
  *  Added the "Search" button to the graphical diff generated by
     the --tk option on the [/help?cmd=diff|diff] command.
  *  Added the "--checkin VERSION" option to the 
     [/help?cmd=diff|diff] command.
  *  Various performance enhancements to the [/help?cmd=diff|diff] command.
  *  Update internal Unicode character tables, used in regular expression
     handling, from version 8.0 to 9.0.
  *  Update the built-in SQLite to version 3.15 (beta). Fossil now requires
     the SQLITE_DBCONFIG_MAINDBNAME interface of SQLite which is only available
     in SQLite version 3.15 and later and so Fossil will not work with
     earlier SQLite versions.
  *  Fix [https://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg23618.html|multi-line timeline bug]

Changes to www/sync.wiki.

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
<p>A client that sends a clone protocol version "3" or greater will
receive artifacts as "cfile" cards while cloning.  This card was
introduced to improve the speed of the transfer of content by sending the
compressed artifact directly from the server database to the client.</p>

<p>Compressed File cards are similar to File cards, sharing the same
in-line "payload" data characteristics and also the same treatment of
direct content or delta content.  It comes in two different formats
depending on whether the artifact is sent directly or as a delta from
some other artifact.</p>

<blockquote>
<b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br>
<b>cfile</b> <i>artifact-id delta-artifact-id usize csize</i> <b>\n</b> <i>content</i><br>
</blockquote>
................................................................................
<i>mtime</i> is the last modification time of the file in seconds
since 1970.  The <i>hash</i> field is the SHA1 hash of the content
for the unversioned file, or "<b>-</b>" for deleted content.
The <i>size</i> field is the (uncompressed) size of the content
in bytes.  The <i>flags</i> field is an integer which is interpreted
as an array of bits.  The 0x0004 bit of <i>flags</i> indicates that
the <i>content</i> is to be omitted.  The content might be omitted if
it is too large to transmit, or if the send merely wants to update the
modification time of the file without changing the files content.
The <i>content</i> is the (uncompressed) content of the file.

<p>The receiver should only accept the uvfile card if the hash and
size match the content and if the mtime is newer than any existing
instance of the same file held by the receiver.  The sender will not
normally transmit a uvfile card unless all these constraints are true,
................................................................................

<p>If the second argument exists and is "1", then the artifact
identified by the first argument is private on the sender and should
be ignored unless a "--private" [/help?cmd=sync|sync] is occurring.

<h4>3.6.1 Unversioned Igot Cards</h4>

<p>Zero or more "uvigot" cards are sent from client to server when
synchronizing unversioned content.  The format of a uvigot card is
as follows:

<blockquote>
<b>uvigot</b> <i>name mtime hash size</i>
</blockquote>








|







 







|







 







|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
<p>A client that sends a clone protocol version "3" or greater will
receive artifacts as "cfile" cards while cloning.  This card was
introduced to improve the speed of the transfer of content by sending the
compressed artifact directly from the server database to the client.</p>

<p>Compressed File cards are similar to File cards, sharing the same
in-line "payload" data characteristics and also the same treatment of
direct content or delta content.  Cfile cards come in two different formats
depending on whether the artifact is sent directly or as a delta from
some other artifact.</p>

<blockquote>
<b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br>
<b>cfile</b> <i>artifact-id delta-artifact-id usize csize</i> <b>\n</b> <i>content</i><br>
</blockquote>
................................................................................
<i>mtime</i> is the last modification time of the file in seconds
since 1970.  The <i>hash</i> field is the SHA1 hash of the content
for the unversioned file, or "<b>-</b>" for deleted content.
The <i>size</i> field is the (uncompressed) size of the content
in bytes.  The <i>flags</i> field is an integer which is interpreted
as an array of bits.  The 0x0004 bit of <i>flags</i> indicates that
the <i>content</i> is to be omitted.  The content might be omitted if
it is too large to transmit, or if the sender merely wants to update the
modification time of the file without changing the files content.
The <i>content</i> is the (uncompressed) content of the file.

<p>The receiver should only accept the uvfile card if the hash and
size match the content and if the mtime is newer than any existing
instance of the same file held by the receiver.  The sender will not
normally transmit a uvfile card unless all these constraints are true,
................................................................................

<p>If the second argument exists and is "1", then the artifact
identified by the first argument is private on the sender and should
be ignored unless a "--private" [/help?cmd=sync|sync] is occurring.

<h4>3.6.1 Unversioned Igot Cards</h4>

<p>Zero or more "uvigot" cards are sent from server to client when
synchronizing unversioned content.  The format of a uvigot card is
as follows:

<blockquote>
<b>uvigot</b> <i>name mtime hash size</i>
</blockquote>

Changes to www/th1.md.

162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
...
515
516
517
518
519
520
521








522
523
524
525
526
527
528
...
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
...
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
  *  regexp
  *  reinitialize
  *  render
  *  repository
  *  searchable
  *  setParameter
  *  setting

  *  styleHeader
  *  styleFooter
  *  tclEval
  *  tclExpr
  *  tclInvoke
  *  tclIsSafe
  *  tclMakeSafe
  *  tclReady
  *  trace
  *  stime
  *  utime
  *  verifyCsrf
  *  wiki

Each of the commands above is documented by a block comment above their
implementation in the th\_main.c or th\_tcl.c source files.

................................................................................

  *  decorate STRING

Renders STRING as wiki content; however, only links are handled.  No
other markup is processed.

<a name="dir"></a>TH1 dir Command
-------------------------------------------

  * dir CHECKIN ?GLOB? ?DETAILS?

Returns a list containing all files in CHECKIN. If GLOB is given only
the files matching the pattern GLOB within CHECKIN will be returned.
If DETAILS is non-zero, the result will be a list-of-lists, with each
element containing at least three elements: the file name, the file
................................................................................

  *  linecount STRING MAX MIN

Returns one more than the number of \n characters in STRING.  But
never returns less than MIN or more than MAX.

<a name="markdown"></a>TH1 markdown Command
---------------------------------------------

  *  markdown STRING

Renders the input string as markdown.  The result is a two-element list.
The first element contains the body, rendered as HTML.  The second element
is the text-only title string.

................................................................................

<a name="setting"></a>TH1 setting Command
-----------------------------------------

  *  setting name

Gets and returns the value of the specified setting.









<a name="styleHeader"></a>TH1 styleHeader Command
-------------------------------------------------

  *  styleHeader TITLE

Render the configured style header.
................................................................................

  *  tclIsSafe

Returns non-zero if the Tcl interpreter is "safe".  The Tcl interpreter
will be created automatically if it has not been already.

<a name="tclMakeSafe"></a>TH1 tclMakeSafe Command
---------------------------------------------

**This command requires the Tcl integration feature.**

  *  tclMakeSafe

Forces the Tcl interpreter into "safe" mode by removing all "unsafe"
commands and variables.  This operation cannot be undone.  The Tcl
................................................................................
<a name="trace"></a>TH1 trace Command
-------------------------------------

  *  trace STRING

Generates a TH1 trace message if TH1 tracing is enabled.

<a name="stime"></a>TH1 stime Command
-------------------------------------

  *  stime

Returns the number of microseconds of CPU time consumed by the current
process in system space.

<a name="utime"></a>TH1 utime Command
-------------------------------------

  *  utime

Returns the number of microseconds of CPU time consumed by the current
process in user space.







>









<







 







|







 







|







 







>
>
>
>
>
>
>
>







 







|







 







<
<
<
<
<
<
<
<







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
...
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
...
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
...
609
610
611
612
613
614
615








616
617
618
619
620
621
622
  *  regexp
  *  reinitialize
  *  render
  *  repository
  *  searchable
  *  setParameter
  *  setting
  *  stime
  *  styleHeader
  *  styleFooter
  *  tclEval
  *  tclExpr
  *  tclInvoke
  *  tclIsSafe
  *  tclMakeSafe
  *  tclReady
  *  trace

  *  utime
  *  verifyCsrf
  *  wiki

Each of the commands above is documented by a block comment above their
implementation in the th\_main.c or th\_tcl.c source files.

................................................................................

  *  decorate STRING

Renders STRING as wiki content; however, only links are handled.  No
other markup is processed.

<a name="dir"></a>TH1 dir Command
---------------------------------

  * dir CHECKIN ?GLOB? ?DETAILS?

Returns a list containing all files in CHECKIN. If GLOB is given only
the files matching the pattern GLOB within CHECKIN will be returned.
If DETAILS is non-zero, the result will be a list-of-lists, with each
element containing at least three elements: the file name, the file
................................................................................

  *  linecount STRING MAX MIN

Returns one more than the number of \n characters in STRING.  But
never returns less than MIN or more than MAX.

<a name="markdown"></a>TH1 markdown Command
-------------------------------------------

  *  markdown STRING

Renders the input string as markdown.  The result is a two-element list.
The first element contains the body, rendered as HTML.  The second element
is the text-only title string.

................................................................................

<a name="setting"></a>TH1 setting Command
-----------------------------------------

  *  setting name

Gets and returns the value of the specified setting.

<a name="stime"></a>TH1 stime Command
-------------------------------------

  *  stime

Returns the number of microseconds of CPU time consumed by the current
process in system space.

<a name="styleHeader"></a>TH1 styleHeader Command
-------------------------------------------------

  *  styleHeader TITLE

Render the configured style header.
................................................................................

  *  tclIsSafe

Returns non-zero if the Tcl interpreter is "safe".  The Tcl interpreter
will be created automatically if it has not been already.

<a name="tclMakeSafe"></a>TH1 tclMakeSafe Command
-------------------------------------------------

**This command requires the Tcl integration feature.**

  *  tclMakeSafe

Forces the Tcl interpreter into "safe" mode by removing all "unsafe"
commands and variables.  This operation cannot be undone.  The Tcl
................................................................................
<a name="trace"></a>TH1 trace Command
-------------------------------------

  *  trace STRING

Generates a TH1 trace message if TH1 tracing is enabled.









<a name="utime"></a>TH1 utime Command
-------------------------------------

  *  utime

Returns the number of microseconds of CPU time consumed by the current
process in user space.