Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Updating from trunk. I solved three merge conflicts about hyperlinks. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | annotate_links |
| Files: | files | file ages | folders |
| SHA1: |
08db320464c7cd19fe8992da6846c6f0 |
| User & Date: | viriketo 2012-08-08 13:46:37.972 |
Context
|
2012-08-20
| ||
| 13:20 | Fixing the automatic calculation of sbs line length, for the case of TABs and UTF8 sequences. I also set the tab size to 4 spaces. check-in: 36cdc17cc8 user: viriketo tags: annotate_links | |
|
2012-08-08
| ||
| 13:46 | Updating from trunk. I solved three merge conflicts about hyperlinks. check-in: 08db320464 user: viriketo tags: annotate_links | |
| 13:22 | When using /zip or /tarball without a UUID, use "trunk" instead of "tip" as the default. Ticket [300fc543b24250e256] check-in: eb0933ca55 user: drh tags: trunk | |
|
2012-04-22
| ||
| 10:09 | Merging from trunk. I solved some conflicts on the report for merges (cherrypick/...), adding some comments, and adopted the trunk solution to unchanged checkin messages. check-in: 40debe4782 user: viriketo tags: annotate_links | |
Changes
Changes to VERSION.
|
| | | 1 | 1.23 |
Changes to auto.def.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# System autoconfiguration. Try: ./configure --help
use cc cc-lib
options {
with-openssl:path|auto|none
=> {Look for openssl in the given path, or auto or none}
with-zlib:path => {Look for zlib in the given path}
with-tcl:path => {Enable Tcl integration, with Tcl in the specified path}
internal-sqlite=1 => {Don't use the internal sqlite, use the system one}
static=0 => {Link a static executable}
lineedit=1 => {Disable line editing}
fossil-debug=0 => {Build with fossil debugging enabled}
| | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# System autoconfiguration. Try: ./configure --help
use cc cc-lib
options {
with-openssl:path|auto|none
=> {Look for openssl in the given path, or auto or none}
with-zlib:path => {Look for zlib in the given path}
with-tcl:path => {Enable Tcl integration, with Tcl in the specified path}
internal-sqlite=1 => {Don't use the internal sqlite, use the system one}
static=0 => {Link a static executable}
lineedit=1 => {Disable line editing}
fossil-debug=0 => {Build with fossil debugging enabled}
json=0 => {Build with fossil JSON API enabled}
}
# sqlite wants these types if possible
cc-with {-includes {stdint.h inttypes.h}} {
cc-check-types uint32_t uint16_t int16_t uint8_t
}
|
| ︙ | ︙ | |||
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
if {[opt-bool fossil-debug]} {
define-append EXTRA_CFLAGS -DFOSSIL_DEBUG
}
if {[opt-bool json]} {
define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON
}
if {[opt-bool static]} {
# XXX: This will not work on all systems.
define-append EXTRA_LDFLAGS -static
}
| > | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
if {[opt-bool fossil-debug]} {
define-append EXTRA_CFLAGS -DFOSSIL_DEBUG
}
if {[opt-bool json]} {
define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON
define FOSSIL_ENABLE_JSON
}
if {[opt-bool static]} {
# XXX: This will not work on all systems.
define-append EXTRA_LDFLAGS -static
}
|
| ︙ | ︙ |
Changes to autosetup/local.tcl.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 |
}
}
}
proc parse-tclconfig-sh-file {filename} {
foreach line [split [readfile $filename] \n] {
if {[regexp {^(TCL_[^=]*)=(.*)$} $line -> name value]} {
set tclconfig($name) [string trim $value ']
}
}
return [array get tclconfig]
}
| > | 18 19 20 21 22 23 24 25 26 27 28 29 30 |
}
}
}
proc parse-tclconfig-sh-file {filename} {
foreach line [split [readfile $filename] \n] {
if {[regexp {^(TCL_[^=]*)=(.*)$} $line -> name value]} {
set value [regsub -all {\$\{.*\}} $value ""]
set tclconfig($name) [string trim $value ']
}
}
return [array get tclconfig]
}
|
Changes to src/Makefile.
|
| | | > | 1 2 3 | all clean: $(MAKE) -C .. $(MAKECMDGOALS) |
Changes to src/add.c.
| ︙ | ︙ | |||
250 251 252 253 254 255 256 |
file_canonical_name(g.argv[i], &fullName, 0);
zName = blob_str(&fullName);
isDir = file_wd_isdir(zName);
if( isDir==1 ){
vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore);
}else if( isDir==0 ){
| | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
file_canonical_name(g.argv[i], &fullName, 0);
zName = blob_str(&fullName);
isDir = file_wd_isdir(zName);
if( isDir==1 ){
vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore);
}else if( isDir==0 ){
fossil_warning("not found: %s", zName);
}else if( file_access(zName, R_OK) ){
fossil_fatal("cannot open %s", zName);
}else{
char *zTreeName = &zName[nRoot];
db_multi_exec(
"INSERT OR IGNORE INTO sfile(x) VALUES(%Q)",
zTreeName
|
| ︙ | ︙ |
Changes to src/allrepo.c.
| ︙ | ︙ | |||
61 62 63 64 65 66 67 | ** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%. ** ** Available operations are: ** ** ignore Arguments are repositories that should be ignored ** by subsequent list, pull, push, rebuild, and sync. ** | | > > > > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | ** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%. ** ** Available operations are: ** ** ignore Arguments are repositories that should be ignored ** by subsequent list, pull, push, rebuild, and sync. ** ** list | ls Display the location of all repositories. ** The --ckout option causes all local checkouts to be ** list instead. ** ** changes Shows all local checkouts that have uncommitted changes ** ** pull Run a "pull" operation on all repositories ** ** push Run a "push" on all repositories ** ** rebuild Rebuild on all repositories ** |
| ︙ | ︙ | |||
83 84 85 86 87 88 89 |
void all_cmd(void){
int n;
Stmt q;
const char *zCmd;
char *zSyscmd;
char *zFossil;
char *zQFilename;
| > | > > > > > > > > | > > > > > > > | | > > > > > > | > > > > > > > > | | | | | > | > > > | | | > > > > | | > | < > | < < < < < < < < < | | < < < > | > > | | | > > > > > | < < | 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 |
void all_cmd(void){
int n;
Stmt q;
const char *zCmd;
char *zSyscmd;
char *zFossil;
char *zQFilename;
int useCheckouts = 0;
int quiet = 0;
int testRun = 0;
int stopOnError = find_option("dontstop",0,0)==0;
int rc;
Bag outOfDate;
/* The undocumented --test option causes no changes to occur to any
** repository, but instead show what would have happened. Intended for
** test and debugging use.
*/
testRun = find_option("test",0,0)!=0;
if( g.argc<3 ){
usage("changes|list|ls|pull|push|rebuild|sync");
}
n = strlen(g.argv[2]);
db_open_config(1);
zCmd = g.argv[2];
if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){
zCmd = "list";
useCheckouts = find_option("ckout","c",0)!=0;
}else if( strncmp(zCmd, "push", n)==0 ){
zCmd = "push -autourl -R";
}else if( strncmp(zCmd, "pull", n)==0 ){
zCmd = "pull -autourl -R";
}else if( strncmp(zCmd, "rebuild", n)==0 ){
zCmd = "rebuild";
}else if( strncmp(zCmd, "sync", n)==0 ){
zCmd = "sync -autourl -R";
}else if( strncmp(zCmd, "test-integrity", n)==0 ){
zCmd = "test-integrity";
}else if( strncmp(zCmd, "changes", n)==0 ){
zCmd = "changes --quiet --header --chdir";
useCheckouts = 1;
stopOnError = 0;
quiet = 1;
}else if( strncmp(zCmd, "ignore", n)==0 ){
int j;
verify_all_options();
db_begin_transaction();
for(j=3; j<g.argc; j++){
char *zSql = mprintf("DELETE FROM global_config"
" WHERE name GLOB 'repo:%q'", g.argv[j]);
if( testRun ){
fossil_print("%s\n", zSql);
}else{
db_multi_exec("%s", zSql);
}
fossil_free(zSql);
}
db_end_transaction(0);
return;
}else{
fossil_fatal("\"all\" subcommand should be one of: "
"changes ignore list ls push pull rebuild sync");
}
verify_all_options();
zFossil = quoteFilename(fossil_nameofexe());
if( useCheckouts ){
db_prepare(&q,
"SELECT substr(name, 7) COLLATE nocase, max(rowid)"
" FROM global_config"
" WHERE substr(name, 1, 6)=='ckout:'"
" GROUP BY 1 ORDER BY 1"
);
}else{
db_prepare(&q,
"SELECT substr(name, 6) COLLATE nocase, max(rowid)"
" FROM global_config"
" WHERE substr(name, 1, 5)=='repo:'"
" GROUP BY 1 ORDER BY 1"
);
}
bag_init(&outOfDate);
while( db_step(&q)==SQLITE_ROW ){
const char *zFilename = db_column_text(&q, 0);
int rowid = db_column_int(&q, 1);
if( file_access(zFilename, 0) || !file_is_canonical(zFilename) ){
bag_insert(&outOfDate, rowid);
continue;
}
if( useCheckouts && file_isdir(zFilename)!=1 ){
bag_insert(&outOfDate, rowid);
continue;
}
if( zCmd[0]=='l' ){
fossil_print("%s\n", zFilename);
continue;
}
zQFilename = quoteFilename(zFilename);
zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename);
if( !quiet || testRun ){
fossil_print("%s\n", zSyscmd);
fflush(stdout);
}
rc = testRun ? 0 : fossil_system(zSyscmd);
free(zSyscmd);
free(zQFilename);
if( stopOnError && rc ){
break;
}
}
db_finalize(&q);
/* If any repositories whose names appear in the ~/.fossil file could not
** be found, remove those names from the ~/.fossil file.
*/
if( bag_count(&outOfDate)>0 ){
Blob sql;
char *zSep = "(";
int rowid;
blob_zero(&sql);
blob_appendf(&sql, "DELETE FROM global_config WHERE rowid IN ");
for(rowid=bag_first(&outOfDate); rowid>0; rowid=bag_next(&outOfDate,rowid)){
blob_appendf(&sql, "%s%d", zSep, rowid);
zSep = ",";
}
blob_appendf(&sql, ")");
if( testRun ){
fossil_print("%s\n", blob_str(&sql));
}else{
db_multi_exec(blob_str(&sql));
}
blob_reset(&sql);
}
}
|
Changes to src/attach.c.
| ︙ | ︙ | |||
73 74 75 76 77 78 79 |
for(i=0; zFilename[i]; i++){
if( zFilename[i]=='/' && zFilename[i+1]!=0 ){
zFilename = &zFilename[i+1];
i = -1;
}
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
| | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
for(i=0; zFilename[i]; i++){
if( zFilename[i]=='/' && zFilename[i+1]!=0 ){
zFilename = &zFilename[i+1];
i = -1;
}
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename);
}else{
zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename);
}
@
@ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
@ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br />
if( zComment ) while( fossil_isspace(zComment[0]) ) zComment++;
if( zComment && zComment[0] ){
@ %w(zComment)<br />
|
| ︙ | ︙ |
Changes to src/blob.c.
| ︙ | ︙ | |||
437 438 439 440 441 442 443 |
if( whence==BLOB_SEEK_SET ){
p->iCursor = offset;
}else if( whence==BLOB_SEEK_CUR ){
p->iCursor += offset;
}else if( whence==BLOB_SEEK_END ){
p->iCursor = p->nUsed + offset - 1;
}
| < < < | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
if( whence==BLOB_SEEK_SET ){
p->iCursor = offset;
}else if( whence==BLOB_SEEK_CUR ){
p->iCursor += offset;
}else if( whence==BLOB_SEEK_END ){
p->iCursor = p->nUsed + offset - 1;
}
if( p->iCursor>p->nUsed ){
p->iCursor = p->nUsed;
}
return p->iCursor;
}
/*
|
| ︙ | ︙ | |||
699 700 701 702 703 704 705 | /* ** Initialize a blob to be the content of a file. If the filename ** is blank or "-" then read from standard input. ** ** Any prior content of the blob is discarded, not freed. ** | | > | 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 |
/*
** Initialize a blob to be the content of a file. If the filename
** is blank or "-" then read from standard input.
**
** Any prior content of the blob is discarded, not freed.
**
** Return the number of bytes read. Calls fossil_panic() error (i.e.
** it exit()s and does not return).
*/
int blob_read_from_file(Blob *pBlob, const char *zFilename){
int size, got;
FILE *in;
if( zFilename==0 || zFilename[0]==0
|| (zFilename[0]=='-' && zFilename[1]==0) ){
return blob_read_from_channel(pBlob, stdin, -1);
|
| ︙ | ︙ | |||
1079 1080 1081 1082 1083 1084 1085 |
assert( (pIn->iCursor+nLen) <= pIn->nUsed );
if( nLen ){
memcpy( pDest, pIn->aData, nLen );
pIn->iCursor += nLen;
}
return nLen;
}
| > > > > > > > > > > > | 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 |
assert( (pIn->iCursor+nLen) <= pIn->nUsed );
if( nLen ){
memcpy( pDest, pIn->aData, nLen );
pIn->iCursor += nLen;
}
return nLen;
}
/*
** Swaps the contents of the given blobs. Results
** are unspecified if either value is NULL or both
** point to the same blob.
*/
void blob_swap( Blob *pLeft, Blob *pRight ){
Blob swap = *pLeft;
*pLeft = *pRight;
*pRight = swap;
}
|
Changes to src/branch.c.
| ︙ | ︙ | |||
319 320 321 322 323 324 325 |
style_submenu_element("Color-Test", "Color-Test", "brlist?colortest");
}else{
style_submenu_element("All", "All", "brlist?all");
}
login_anonymous_available();
style_sidebox_begin("Nomenclature:", "33%");
@ <ol>
| | | | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
style_submenu_element("Color-Test", "Color-Test", "brlist?colortest");
}else{
style_submenu_element("All", "All", "brlist?all");
}
login_anonymous_available();
style_sidebox_begin("Nomenclature:", "33%");
@ <ol>
@ <li> An <div class="sideboxDescribed">%z(href("brlist"))
@ open branch</a></div> is a branch that has one or
@ more %z(href("leaves"))open leaves.</a>
@ The presence of open leaves presumably means
@ that the branch is still being extended with new check-ins.</li>
@ <li> A <div class="sideboxDescribed">%z(href("brlist?closed"))
@ closed branch</a></div> is a branch with only
@ <div class="sideboxDescribed">%z(href("leaves?closed"))
@ closed leaves</a></div>.
@ Closed branches are fixed and do not change (unless they are first
@ reopened)</li>
@ </ol>
style_sidebox_end();
branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
|
| ︙ | ︙ | |||
354 355 356 357 358 359 360 |
@ <ul>
cnt++;
}
if( colorTest ){
const char *zColor = hash_color(zBr);
@ <li><span style="background-color: %s(zColor)">
@ %h(zBr) → %s(zColor)</span></li>
| < < | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
@ <ul>
cnt++;
}
if( colorTest ){
const char *zColor = hash_color(zBr);
@ <li><span style="background-color: %s(zColor)">
@ %h(zBr) → %s(zColor)</span></li>
}else{
@ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li>
}
}
if( cnt ){
@ </ul>
}
db_finalize(&q);
@ <script type="text/JavaScript">
|
| ︙ | ︙ | |||
380 381 382 383 384 385 386 |
/*
** This routine is called while for each check-in that is rendered by
** the timeline of a "brlist" page. Add some additional hyperlinks
** to the end of the line.
*/
static void brtimeline_extra(int rid){
Stmt q;
| | | | 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 |
/*
** This routine is called while for each check-in that is rendered by
** the timeline of a "brlist" page. Add some additional hyperlinks
** to the end of the line.
*/
static void brtimeline_extra(int rid){
Stmt q;
if( !g.perm.Hyperlink ) return;
db_prepare(&q,
"SELECT substr(tagname,5) FROM tagxref, tag"
" WHERE tagxref.rid=%d"
" AND tagxref.tagid=tag.tagid"
" AND tagxref.tagtype>0"
" AND tag.tagname GLOB 'sym-*'",
rid
);
while( db_step(&q)==SQLITE_ROW ){
const char *zTagName = db_column_text(&q, 0);
@ %z(href("%R/timeline?r=%T",zTagName))[timeline]</a>
}
db_finalize(&q);
}
/*
** WEBPAGE: brtimeline
**
|
| ︙ | ︙ |
Changes to src/browse.c.
| ︙ | ︙ | |||
75 76 77 78 79 80 81 |
*/
void hyperlinked_path(const char *zPath, Blob *pOut, const char *zCI){
int i, j;
char *zSep = "";
for(i=0; zPath[i]; i=j){
for(j=i; zPath[j] && zPath[j]!='/'; j++){}
| | > | | > | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
*/
void hyperlinked_path(const char *zPath, Blob *pOut, const char *zCI){
int i, j;
char *zSep = "";
for(i=0; zPath[i]; i=j){
for(j=i; zPath[j] && zPath[j]!='/'; j++){}
if( zPath[j] && g.perm.Hyperlink ){
if( zCI ){
char *zLink = href("%R/dir?ci=%S&name=%#T", zCI, j, zPath);
blob_appendf(pOut, "%s%z%#h</a>",
zSep, zLink, j-i, &zPath[i]);
}else{
char *zLink = href("%R/dir?name=%#T", j, zPath);
blob_appendf(pOut, "%s%z%#h</a>",
zSep, zLink, j-i, &zPath[i]);
}
}else{
blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]);
}
zSep = "/";
while( zPath[j]=='/' ){ j++; }
}
|
| ︙ | ︙ | |||
116 117 118 119 120 121 122 | int rid = 0; char *zUuid = 0; Blob dirname; Manifest *pM = 0; const char *zSubdirLink; login_check_credentials(); | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
int rid = 0;
char *zUuid = 0;
Blob dirname;
Manifest *pM = 0;
const char *zSubdirLink;
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
style_header("File List");
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
/* If the name= parameter is an empty string, make it a NULL pointer */
if( zD && strlen(zD)==0 ){ zD = 0; }
|
| ︙ | ︙ | |||
153 154 155 156 157 158 159 |
blob_append(&dirname, "in the top-level directory", -1);
zPrefix = "";
}
if( zCI ){
char zShort[20];
memcpy(zShort, zUuid, 10);
zShort[10] = 0;
| | | | | | | | | < | | | | | 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 |
blob_append(&dirname, "in the top-level directory", -1);
zPrefix = "";
}
if( zCI ){
char zShort[20];
memcpy(zShort, zUuid, 10);
zShort[10] = 0;
@ <h2>Files of check-in [%z(href("vinfo?name=%T",zUuid))%s(zShort)</a>]
@ %s(blob_str(&dirname))</h2>
zSubdirLink = mprintf("%R/dir?ci=%S&name=%T", zUuid, zPrefix);
if( zD ){
style_submenu_element("Top", "Top", "%R/dir?ci=%S", zUuid);
style_submenu_element("All", "All", "%R/dir?name=%t", zD);
}else{
style_submenu_element("All", "All", "%R/dir");
}
}else{
int hasTrunk;
@ <h2>The union of all files from all check-ins
@ %s(blob_str(&dirname))</h2>
hasTrunk = db_exists(
"SELECT 1 FROM tagxref WHERE tagid=%d AND value='trunk'",
TAG_BRANCH);
zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
if( zD ){
style_submenu_element("Top", "Top", "%R/dir");
style_submenu_element("Tip", "Tip", "%R/dir?name=%t&ci=tip", zD);
if( hasTrunk ){
style_submenu_element("Trunk", "Trunk", "%R/dir?name=%t&ci=trunk",
zD);
}
}else{
style_submenu_element("Tip", "Tip", "%R/dir?ci=tip");
if( hasTrunk ){
style_submenu_element("Trunk", "Trunk", "%R/dir?ci=trunk");
}
}
}
/* Compute the temporary table "localfiles" containing the names
** of all files and subdirectories in the zD[] directory.
**
|
| ︙ | ︙ | |||
276 277 278 279 280 281 282 |
@ </ul></td><td class="browser"><ul class="browser">
i = 0;
}
i++;
zFN = db_column_text(&q, 0);
if( zFN[0]=='/' ){
zFN++;
| | | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
@ </ul></td><td class="browser"><ul class="browser">
i = 0;
}
i++;
zFN = db_column_text(&q, 0);
if( zFN[0]=='/' ){
zFN++;
@ <li>%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li>
}else if( zCI ){
const char *zUuid = db_column_text(&q, 1);
@ <li>%z(href("%R/artifact/%s",zUuid))%h(zFN)</a></li>
}else{
@ <li>%z(href("%R/finfo?name=%T%T",zPrefix,zFN))%h(zFN)
@ </a></li>
}
}
db_finalize(&q);
manifest_destroy(pM);
@ </ul></td></tr></table>
style_footer();
}
|
Changes to src/checkin.c.
| ︙ | ︙ | |||
40 41 42 43 44 45 46 |
Stmt q;
int nPrefix = strlen(zPrefix);
int nErr = 0;
Blob rewrittenPathname;
db_prepare(&q,
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
" FROM vfile "
| | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
Stmt q;
int nPrefix = strlen(zPrefix);
int nErr = 0;
Blob rewrittenPathname;
db_prepare(&q,
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
" FROM vfile "
" WHERE is_selected(id)"
" AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
);
blob_zero(&rewrittenPathname);
while( db_step(&q)==SQLITE_ROW ){
const char *zPathname = db_column_text(&q,0);
const char *zDisplayName = zPathname;
int isDeleted = db_column_int(&q, 1);
|
| ︙ | ︙ | |||
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 |
**
** Options:
** --abs-paths Display absolute pathnames.
** --rel-paths Display pathnames relative to the current working
** directory.
** --sha1sum Verify file status using SHA1 hashing rather
** than relying on file mtimes.
**
** See also: extra, ls, status
*/
void changes_cmd(void){
Blob report;
int vid;
int useSha1sum = find_option("sha1sum", 0, 0)!=0;
int cwdRelative = 0;
db_must_be_within_tree();
cwdRelative = determine_cwd_relative_option();
blob_zero(&report);
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0, useSha1sum);
status_report(&report, "", 0, cwdRelative);
blob_write_to_file(&report, "-");
}
/*
** COMMAND: status
**
** Usage: %fossil status ?OPTIONS?
| > > > > > > > > > > > | 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 |
**
** Options:
** --abs-paths Display absolute pathnames.
** --rel-paths Display pathnames relative to the current working
** directory.
** --sha1sum Verify file status using SHA1 hashing rather
** than relying on file mtimes.
** --header Identify the repository if there are changes
** -v Say "no changes" if there are none
**
** See also: extra, ls, status
*/
void changes_cmd(void){
Blob report;
int vid;
int useSha1sum = find_option("sha1sum", 0, 0)!=0;
int showHdr = find_option("header",0,0)!=0;
int verbose = find_option("verbose","v",0)!=0;
int cwdRelative = 0;
db_must_be_within_tree();
cwdRelative = determine_cwd_relative_option();
blob_zero(&report);
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0, useSha1sum);
status_report(&report, "", 0, cwdRelative);
if( verbose && blob_size(&report)==0 ){
blob_append(&report, " (none)\n", -1);
}
if( showHdr && blob_size(&report)>0 ){
fossil_print("Changes for %s at %s:\n", db_get("project-name","???"),
g.zLocalRoot);
}
blob_write_to_file(&report, "-");
}
/*
** COMMAND: status
**
** Usage: %fossil status ?OPTIONS?
|
| ︙ | ︙ | |||
672 673 674 675 676 677 678 |
}
blob_appendf(pOut, "C %F\n", blob_str(pComment));
zDate = date_in_standard_format(zDateOvrd ? zDateOvrd : "now");
blob_appendf(pOut, "D %s\n", zDate);
zDate[10] = ' ';
db_prepare(&q,
"SELECT pathname, uuid, origname, blob.rid, isexe, islink,"
| | | | > | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 |
}
blob_appendf(pOut, "C %F\n", blob_str(pComment));
zDate = date_in_standard_format(zDateOvrd ? zDateOvrd : "now");
blob_appendf(pOut, "D %s\n", zDate);
zDate[10] = ' ';
db_prepare(&q,
"SELECT pathname, uuid, origname, blob.rid, isexe, islink,"
" is_selected(vfile.id)"
" FROM vfile JOIN blob ON vfile.mrid=blob.rid"
" WHERE (NOT deleted OR NOT is_selected(vfile.id))"
" AND vfile.vid=%d"
" ORDER BY if_selected(vfile.id, pathname, origname)",
vid);
blob_zero(&filename);
blob_appendf(&filename, "%s", g.zLocalRoot);
nBasename = blob_size(&filename);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zUuid = db_column_text(&q, 1);
const char *zOrig = db_column_text(&q, 2);
|
| ︙ | ︙ | |||
972 973 974 975 976 977 978 |
zComment = find_option("comment","m",1);
forceFlag = find_option("force", "f", 0)!=0;
zBranch = find_option("branch","b",1);
zColor = find_option("bgcolor",0,1);
zBrClr = find_option("branchcolor",0,1);
while( (zTag = find_option("tag",0,1))!=0 ){
if( zTag[0]==0 ) continue;
| | | 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 |
zComment = find_option("comment","m",1);
forceFlag = find_option("force", "f", 0)!=0;
zBranch = find_option("branch","b",1);
zColor = find_option("bgcolor",0,1);
zBrClr = find_option("branchcolor",0,1);
while( (zTag = find_option("tag",0,1))!=0 ){
if( zTag[0]==0 ) continue;
azTag = fossil_realloc((void *)azTag, sizeof(char*)*(nTag+2));
azTag[nTag++] = zTag;
azTag[nTag] = 0;
}
zComFile = find_option("message-file", "M", 1);
if( find_option("private",0,0) ){
g.markPrivate = 1;
if( zBranch==0 ) zBranch = "private";
|
| ︙ | ︙ | |||
1081 1082 1083 1084 1085 1086 1087 |
*/
if( g.aCommitFile ){
Blob unmodified;
memset(&unmodified, 0, sizeof(Blob));
blob_init(&unmodified, 0, 0);
db_blob(&unmodified,
"SELECT pathname FROM vfile"
| | | 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 |
*/
if( g.aCommitFile ){
Blob unmodified;
memset(&unmodified, 0, sizeof(Blob));
blob_init(&unmodified, 0, 0);
db_blob(&unmodified,
"SELECT pathname FROM vfile"
" WHERE chnged = 0 AND origname IS NULL AND is_selected(id)"
);
if( strlen(blob_str(&unmodified)) ){
fossil_fatal("file %s has not changed", blob_str(&unmodified));
}
}
/*
|
| ︙ | ︙ | |||
1142 1143 1144 1145 1146 1147 1148 |
/* Step 1: Insert records for all modified files into the blob
** table. If there were arguments passed to this command, only
** the identified fils are inserted (if they have been modified).
*/
db_prepare(&q,
"SELECT id, %Q || pathname, mrid, %s FROM vfile "
| | | 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 |
/* Step 1: Insert records for all modified files into the blob
** table. If there were arguments passed to this command, only
** the identified fils are inserted (if they have been modified).
*/
db_prepare(&q,
"SELECT id, %Q || pathname, mrid, %s FROM vfile "
"WHERE chnged==1 AND NOT deleted AND is_selected(id)",
g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob",""))
);
while( db_step(&q)==SQLITE_ROW ){
int id, rid;
const char *zFullname;
Blob content;
int crnlOk;
|
| ︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 |
free(zManifestFile);
blob_reset(&muuid);
}
/* Update the vfile and vmerge tables */
db_multi_exec(
| | | | 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 |
free(zManifestFile);
blob_reset(&muuid);
}
/* Update the vfile and vmerge tables */
db_multi_exec(
"DELETE FROM vfile WHERE (vid!=%d OR deleted) AND is_selected(id);"
"DELETE FROM vmerge;"
"UPDATE vfile SET vid=%d;"
"UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
" WHERE is_selected(id);"
, vid, nvid
);
db_lset_int("checkout", nvid);
if( useCksum ){
/* Verify that the repository checksum matches the expected checksum
** calculated before the checkin started (and stored as the R record
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
289 290 291 292 293 294 295 296 297 298 299 |
*/
void close_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
db_must_be_within_tree();
if( !forceFlag && unsaved_changes()==1 ){
fossil_fatal("there are unsaved changes in the current checkout");
}
unlink_local_database(1);
db_close(1);
unlink_local_database(0);
}
| > > > | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
*/
void close_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
db_must_be_within_tree();
if( !forceFlag && unsaved_changes()==1 ){
fossil_fatal("there are unsaved changes in the current checkout");
}
if( db_is_writeable("repository") ){
db_multi_exec("DELETE FROM config WHERE name='ckout:%q'", g.zLocalRoot);
}
unlink_local_database(1);
db_close(1);
unlink_local_database(0);
}
|
Changes to src/configure.c.
| ︙ | ︙ | |||
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
{ "logo-mimetype", CONFIGSET_SKIN },
{ "logo-image", CONFIGSET_SKIN },
{ "background-mimetype", CONFIGSET_SKIN },
{ "background-image", CONFIGSET_SKIN },
{ "index-page", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
#ifdef FOSSIL_ENABLE_TCL
{ "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
#endif
{ "project-name", CONFIGSET_PROJ },
{ "project-description", CONFIGSET_PROJ },
{ "manifest", CONFIGSET_PROJ },
| > > > | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
{ "logo-mimetype", CONFIGSET_SKIN },
{ "logo-image", CONFIGSET_SKIN },
{ "background-mimetype", CONFIGSET_SKIN },
{ "background-image", CONFIGSET_SKIN },
{ "index-page", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
#ifdef FOSSIL_ENABLE_TCL
{ "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
#endif
{ "project-name", CONFIGSET_PROJ },
{ "project-description", CONFIGSET_PROJ },
{ "manifest", CONFIGSET_PROJ },
|
| ︙ | ︙ |
Changes to src/cson_amalgamation.c.
| ︙ | ︙ | |||
1420 1421 1422 1423 1424 1425 1426 |
#if defined(__cplusplus)
extern "C" {
#endif
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 |
#if defined(__cplusplus)
extern "C" {
#endif
/**
This type holds the "vtbl" for type-specific operations when
working with cson_value objects.
All cson_values of a given logical type share a pointer to a single
library-internal instance of this class.
|
| ︙ | ︙ | |||
2312 2313 2314 2315 2316 2317 2318 |
/** Returns true if v is not NULL and has the given type ID. */
static char cson_value_is_a( cson_value const * v, cson_type_id is )
{
return (v && v->api && (v->api->typeID == is)) ? 1 : 0;
}
#endif
| < < | 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 |
/** Returns true if v is not NULL and has the given type ID. */
static char cson_value_is_a( cson_value const * v, cson_type_id is )
{
return (v && v->api && (v->api->typeID == is)) ? 1 : 0;
}
#endif
cson_type_id cson_value_type_id( cson_value const * v )
{
return (v && v->api) ? v->api->typeID : CSON_TYPE_UNDEF;
}
char cson_value_is_undef( cson_value const * v )
{
return ( !v || !v->api || (v->api==&cson_value_api_undef))
? 1 : 0;
}
#define ISA(T,TID) char cson_value_is_##T( cson_value const * v ) { \
|
| ︙ | ︙ | |||
4470 4471 4472 4473 4474 4475 4476 | - (inp) = is a pointer to the pointer to the start of the input. - (separator) = the separator character - (end) = a pointer to NULL. i.e. (*end == NULL) | | | 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 | - (inp) = is a pointer to the pointer to the start of the input. - (separator) = the separator character - (end) = a pointer to NULL. i.e. (*end == NULL) This function scans *inp for the given separator char or a NUL char. Successive separators at the start of *inp are skipped. The effect is that, when this function is called in a loop, all neighboring separators are ignored. e.g. the string "aa.bb...cc" will tokenize to the list (aa,bb,cc) if the separator is '.' and to (aa.,...cc) if the separator is 'b'. Returns 0 (false) if it finds no token, else non-0 (true). |
| ︙ | ︙ |
Changes to src/cson_amalgamation.h.
| ︙ | ︙ | |||
130 131 132 133 134 135 136 137 138 139 140 141 142 143 | */ /** @def CSON_DOUBLE_T_PFMT printf()-compatible format token for cson_double_t. */ typedef struct cson_value cson_value; /** @struct cson_value The core value type of this API. It is opaque to clients, and only the cson public API should be used for setting or inspecting their values. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
*/
/** @def CSON_DOUBLE_T_PFMT
printf()-compatible format token for cson_double_t.
*/
/**
Type IDs corresponding to JavaScript/JSON types.
These are only in the public API to allow O(1) client-side
dispatching based on cson_value types.
*/
enum cson_type_id {
/**
The special "undefined" value constant.
Its value must be 0 for internal reasons.
*/
CSON_TYPE_UNDEF = 0,
/**
The special "null" value constant.
*/
CSON_TYPE_NULL = 1,
/**
The bool value type.
*/
CSON_TYPE_BOOL = 2,
/**
The integer value type, represented in this library
by cson_int_t.
*/
CSON_TYPE_INTEGER = 3,
/**
The double value type, represented in this library
by cson_double_t.
*/
CSON_TYPE_DOUBLE = 4,
/** The immutable string type. This library stores strings
as immutable UTF8.
*/
CSON_TYPE_STRING = 5,
/** The "Array" type. */
CSON_TYPE_ARRAY = 6,
/** The "Object" type. */
CSON_TYPE_OBJECT = 7
};
/**
Convenience typedef.
*/
typedef enum cson_type_id cson_type_id;
/**
Convenience typedef.
*/
typedef struct cson_value cson_value;
/** @struct cson_value
The core value type of this API. It is opaque to clients, and
only the cson public API should be used for setting or
inspecting their values.
|
| ︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 | @see cson_value_new_integer() @see cson_value_new_double() @see cson_value_new_bool() @see cson_value_true() @see cson_value_false() @see cson_value_null() @see cson_value_free() */ /** @var cson_rc This object defines the error codes used by cson. Library routines which return int values almost always return a | > | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | @see cson_value_new_integer() @see cson_value_new_double() @see cson_value_new_bool() @see cson_value_true() @see cson_value_false() @see cson_value_null() @see cson_value_free() @see cson_value_type_id() */ /** @var cson_rc This object defines the error codes used by cson. Library routines which return int values almost always return a |
| ︙ | ︙ | |||
738 739 740 741 742 743 744 745 746 747 748 749 750 751 | /** Convenience wrapper around cson_output_FILE() which writes to the given filename, destroying any existing contents. Returns cson_rc.IOError if the file cannot be opened. @see cson_output_FILE() */ int cson_output_filename( cson_value const * src, char const * dest, cson_output_opt const * fmt ); /** Returns true if v is null, v->api is NULL, or v holds the special undefined value. */ char cson_value_is_undef( cson_value const * v ); /** Returns true if v contains a null value. */ char cson_value_is_null( cson_value const * v ); /** Returns true if v contains a bool value. */ char cson_value_is_bool( cson_value const * v ); | > > > > > > | 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 | /** Convenience wrapper around cson_output_FILE() which writes to the given filename, destroying any existing contents. Returns cson_rc.IOError if the file cannot be opened. @see cson_output_FILE() */ int cson_output_filename( cson_value const * src, char const * dest, cson_output_opt const * fmt ); /** Returns the virtual type of v, or CSON_TYPE_UNDEF if !v. */ cson_type_id cson_value_type_id( cson_value const * v ); /** Returns true if v is null, v->api is NULL, or v holds the special undefined value. */ char cson_value_is_undef( cson_value const * v ); /** Returns true if v contains a null value. */ char cson_value_is_null( cson_value const * v ); /** Returns true if v contains a bool value. */ char cson_value_is_bool( cson_value const * v ); |
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
int nPrepare; /* Number of calls to sqlite3_prepare() */
int nDeleteOnFail; /* Number of entries in azDeleteOnFail[] */
struct sCommitHook {
int (*xHook)(void); /* Functions to call at db_end_transaction() */
int sequence; /* Call functions in sequence order */
} aHook[5];
char *azDeleteOnFail[3]; /* Files to delete on a failure */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
| > > > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
int nPrepare; /* Number of calls to sqlite3_prepare() */
int nDeleteOnFail; /* Number of entries in azDeleteOnFail[] */
struct sCommitHook {
int (*xHook)(void); /* Functions to call at db_end_transaction() */
int sequence; /* Call functions in sequence order */
} aHook[5];
char *azDeleteOnFail[3]; /* Files to delete on a failure */
char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
int nBeforeCommit; /* Number of entries in azBeforeCommit */
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
|
| ︙ | ︙ | |||
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
/*
** Begin and end a nested transaction
*/
void db_begin_transaction(void){
if( db.nBegin==0 ){
db_multi_exec("BEGIN");
sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
}
db.nBegin++;
}
void db_end_transaction(int rollbackFlag){
if( g.db==0 ) return;
if( db.nBegin<=0 ) return;
if( rollbackFlag ) db.doRollback = 1;
db.nBegin--;
if( db.nBegin==0 ){
int i;
| > > > > > > > | > | 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 |
/*
** Begin and end a nested transaction
*/
void db_begin_transaction(void){
if( db.nBegin==0 ){
db_multi_exec("BEGIN");
sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
db.nPriorChanges = sqlite3_total_changes(g.db);
}
db.nBegin++;
}
void db_end_transaction(int rollbackFlag){
if( g.db==0 ) return;
if( db.nBegin<=0 ) return;
if( rollbackFlag ) db.doRollback = 1;
db.nBegin--;
if( db.nBegin==0 ){
int i;
if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){
while( db.nBeforeCommit ){
db.nBeforeCommit--;
sqlite3_exec(g.db, db.azBeforeCommit[db.nBeforeCommit], 0, 0, 0);
sqlite3_free(db.azBeforeCommit[db.nBeforeCommit]);
}
leaf_do_pending_checks();
}
for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){
db.doRollback |= db.aHook[i].xHook();
}
while( db.pAllStmt ){
db_finalize(db.pAllStmt);
}
db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
|
| ︙ | ︙ | |||
485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
rc = sqlite3_exec(g.db, blob_buffer(&sql), 0, 0, &zErr);
if( rc!=SQLITE_OK ){
db_err("%s\n%s", zErr, blob_buffer(&sql));
}
blob_reset(&sql);
return rc;
}
/*
** Execute a query and return a single integer value.
*/
i64 db_int64(i64 iDflt, const char *zSql, ...){
va_list ap;
Stmt s;
| > > > > > > > > > > > > > > | 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 |
rc = sqlite3_exec(g.db, blob_buffer(&sql), 0, 0, &zErr);
if( rc!=SQLITE_OK ){
db_err("%s\n%s", zErr, blob_buffer(&sql));
}
blob_reset(&sql);
return rc;
}
/*
** Optionally make the following changes to the database if feasible and
** convenient. Do not start a transaction for these changes, but only
** make these changes if other changes are also being made.
*/
void db_optional_sql(const char *zDb, const char *zSql, ...){
if( db_is_writeable(zDb) && db.nBeforeCommit < count(db.azBeforeCommit) ){
va_list ap;
va_start(ap, zSql);
db.azBeforeCommit[db.nBeforeCommit++] = sqlite3_vmprintf(zSql, ap);
va_end(ap);
}
}
/*
** Execute a query and return a single integer value.
*/
i64 db_int64(i64 iDflt, const char *zSql, ...){
va_list ap;
Stmt s;
|
| ︙ | ︙ | |||
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 |
** Return TRUE if the schema is out-of-date
*/
int db_schema_is_outofdate(void){
return db_exists("SELECT 1 FROM config"
" WHERE name='aux-schema'"
" AND value<>'%s'", AUX_SCHEMA);
}
/*
** Verify that the repository schema is correct. If it is not correct,
** issue a fatal error and die.
*/
void db_verify_schema(void){
if( db_schema_is_outofdate() ){
| > > > > > > > | 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 |
** Return TRUE if the schema is out-of-date
*/
int db_schema_is_outofdate(void){
return db_exists("SELECT 1 FROM config"
" WHERE name='aux-schema'"
" AND value<>'%s'", AUX_SCHEMA);
}
/*
** Return true if the database is writeable
*/
int db_is_writeable(const char *zName){
return g.db!=0 && !sqlite3_db_readonly(g.db, db_name(zName));
}
/*
** Verify that the repository schema is correct. If it is not correct,
** issue a fatal error and die.
*/
void db_verify_schema(void){
if( db_schema_is_outofdate() ){
|
| ︙ | ︙ | |||
1049 1050 1051 1052 1053 1054 1055 |
/*
** Open the local database. If unable, exit with an error.
*/
void db_must_be_within_tree(void){
if( db_open_local()==0 ){
| | | 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 |
/*
** Open the local database. If unable, exit with an error.
*/
void db_must_be_within_tree(void){
if( db_open_local()==0 ){
fossil_fatal("current directory is not within an open checkout");
}
db_open_repository(0);
db_verify_schema();
}
/*
** Close the database connection.
|
| ︙ | ︙ | |||
1328 1329 1330 1331 1332 1333 1334 |
}else if( argc==2 ){
zP = (const char*)sqlite3_value_text(argv[1]);
if( zP ) sqlite3_result_text(context, zP, -1, SQLITE_TRANSIENT);
}
}
/*
| | > > | > > > > > | | > > | > > | | | > > > > | > > > | | 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 |
}else if( argc==2 ){
zP = (const char*)sqlite3_value_text(argv[1]);
if( zP ) sqlite3_result_text(context, zP, -1, SQLITE_TRANSIENT);
}
}
/*
** SQL function:
**
** is_selected(id)
** if_selected(id, X, Y)
**
** On the commit command, when filenames are specified (in order to do
** a partial commit) the vfile.id values for the named files are loaded
** into the g.aCommitFile[] array. This function looks at that array
** to see if a file is named on the command-line.
**
** In the first form (1 argument) return TRUE if either no files are
** named on the command line (g.aCommitFile is NULL meaning that all
** changes are to be committed) or if id is found in g.aCommitFile[]
** (meaning that id was named on the command-line).
**
** In the second form (3 arguments) return argument X if true and Y
** if false. Except if Y is NULL then always return X.
*/
static void file_is_selected(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int rc = 0;
assert(argc==1 || argc==3);
if( g.aCommitFile ){
int iId = sqlite3_value_int(argv[0]);
int ii;
for(ii=0; g.aCommitFile[ii]; ii++){
if( iId==g.aCommitFile[ii] ){
rc = 1;
break;
}
}
}else{
rc = 1;
}
if( argc==1 ){
sqlite3_result_int(context, rc);
}else{
assert( argc==3 );
assert( rc==0 || rc==1 );
if( sqlite3_value_type(argv[2-rc])==SQLITE_NULL ) rc = 1-rc;
sqlite3_result_value(context, argv[2-rc]);
}
}
/*
** Convert the input string into an SHA1. Make a notation in the
** CONCEALED table so that the hash can be undo using the db_reveal()
** function at some later time.
|
| ︙ | ︙ | |||
1427 1428 1429 1430 1431 1432 1433 |
LOCAL void db_connection_init(void){
sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
sqlite3_create_function(
| | > > > | 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 |
LOCAL void db_connection_init(void){
sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
sqlite3_create_function(
g.db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0
);
sqlite3_create_function(
g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
);
if( g.fSqlTrace ){
sqlite3_trace(g.db, db_sql_trace, 0);
}
}
/*
|
| ︙ | ︙ | |||
1711 1712 1713 1714 1715 1716 1717 1718 |
Blob localRoot;
file_canonical_name(g.zLocalRoot, &localRoot, 1);
db_multi_exec(
"REPLACE INTO global_config(name, value)"
"VALUES('ckout:%q','%q');",
blob_str(&localRoot), blob_str(&full)
);
blob_reset(&localRoot);
| > > > > > > | | > | 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 |
Blob localRoot;
file_canonical_name(g.zLocalRoot, &localRoot, 1);
db_multi_exec(
"REPLACE INTO global_config(name, value)"
"VALUES('ckout:%q','%q');",
blob_str(&localRoot), blob_str(&full)
);
db_swap_connections();
db_optional_sql("repository",
"REPLACE INTO config(name,value,mtime)"
"VALUES('ckout:%q',1,now())",
blob_str(&localRoot)
);
blob_reset(&localRoot);
}else{
db_swap_connections();
}
blob_reset(&full);
}
/*
** COMMAND: open
**
** Usage: %fossil open FILENAME ?VERSION? ?OPTIONS?
|
| ︙ | ︙ | |||
1752 1753 1754 1755 1756 1757 1758 |
usage("REPOSITORY-FILENAME ?VERSION?");
}
if( !allowNested && db_open_local() ){
fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
}
file_canonical_name(g.argv[2], &path, 0);
db_open_repository(blob_str(&path));
| > > > > > | | | 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 |
usage("REPOSITORY-FILENAME ?VERSION?");
}
if( !allowNested && db_open_local() ){
fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
}
file_canonical_name(g.argv[2], &path, 0);
db_open_repository(blob_str(&path));
#if defined(_WIN32)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif
db_init_database(LOCALDB_NAME, zLocalSchema, (char*)0);
db_delete_on_failure(LOCALDB_NAME);
db_open_local();
db_lset("repository", g.argv[2]);
db_record_repository_filename(blob_str(&path));
vid = db_int(0, "SELECT pid FROM plink y"
" WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)");
if( vid==0 ){
db_lset_int("checkout", 1);
|
| ︙ | ︙ | |||
1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 |
char const *def; /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
{ "access-log", 0, 0, 0, "off" },
{ "allow-symlinks",0, 0, 1, "off" },
{ "auto-captcha", "autocaptcha", 0, 0, "on" },
{ "auto-shun", 0, 0, 0, "on" },
{ "autosync", 0, 0, 0, "on" },
{ "binary-glob", 0, 32, 1, "" },
{ "clearsign", 0, 0, 0, "off" },
{ "case-sensitive",0, 0, 0, "on" },
{ "crnl-glob", 0, 16, 1, "" },
{ "default-perms", 0, 16, 0, "u" },
| > | 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 |
char const *def; /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
{ "access-log", 0, 0, 0, "off" },
{ "allow-symlinks",0, 0, 1, "off" },
{ "auto-captcha", "autocaptcha", 0, 0, "on" },
{ "auto-hyperlink",0, 0, 0, "on", },
{ "auto-shun", 0, 0, 0, "on" },
{ "autosync", 0, 0, 0, "on" },
{ "binary-glob", 0, 32, 1, "" },
{ "clearsign", 0, 0, 0, "off" },
{ "case-sensitive",0, 0, 0, "on" },
{ "crnl-glob", 0, 16, 1, "" },
{ "default-perms", 0, 16, 0, "u" },
|
| ︙ | ︙ | |||
1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 | ** (existing links in repository created on Unix become ** plain-text files with link destination path inside). ** Default: off ** ** auto-captcha If enabled, the Login page provides a button to ** fill in the captcha password. Default: on ** ** auto-shun If enabled, automatically pull the shunning list ** from a server to which the client autosyncs. ** Default: on ** ** autosync If enabled, automatically pull prior to commit ** or update and automatically push after commit or ** tag or branch creation. If the value is "pullonly" | > > > > > | 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 | ** (existing links in repository created on Unix become ** plain-text files with link destination path inside). ** Default: off ** ** auto-captcha If enabled, the Login page provides a button to ** fill in the captcha password. Default: on ** ** auto-hyperlink Use javascript to enable hyperlinks on web pages ** for all users (regardless of the "h" privilege) if the ** User-Agent string in the HTTP header look like it came ** from real person, not a spider or bot. Default: on ** ** auto-shun If enabled, automatically pull the shunning list ** from a server to which the client autosyncs. ** Default: on ** ** autosync If enabled, automatically pull prior to commit ** or update and automatically push after commit or ** tag or branch creation. If the value is "pullonly" |
| ︙ | ︙ |
Changes to src/descendants.c.
| ︙ | ︙ | |||
160 161 162 163 164 165 166 |
*/
void compute_ancestors(int rid, int N){
Bag seen;
PQueue queue;
Stmt ins;
Stmt q;
bag_init(&seen);
| | | | | | | 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 |
*/
void compute_ancestors(int rid, int N){
Bag seen;
PQueue queue;
Stmt ins;
Stmt q;
bag_init(&seen);
pqueuex_init(&queue);
bag_insert(&seen, rid);
pqueuex_insert(&queue, rid, 0.0, 0);
db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)");
db_prepare(&q,
"SELECT a.pid, b.mtime FROM plink a LEFT JOIN plink b ON b.cid=a.pid"
" WHERE a.cid=:rid"
);
while( (N--)>0 && (rid = pqueuex_extract(&queue, 0))!=0 ){
db_bind_int(&ins, ":rid", rid);
db_step(&ins);
db_reset(&ins);
db_bind_int(&q, ":rid", rid);
while( db_step(&q)==SQLITE_ROW ){
int pid = db_column_int(&q, 0);
double mtime = db_column_double(&q, 1);
if( bag_insert(&seen, pid) ){
pqueuex_insert(&queue, pid, -mtime, 0);
}
}
db_reset(&q);
}
bag_clear(&seen);
pqueuex_clear(&queue);
db_finalize(&ins);
db_finalize(&q);
}
/*
** Compute up to N direct ancestors (merge ancestors do not count)
** for the check-in rid and put them in a table named "ancestor".
|
| ︙ | ︙ | |||
235 236 237 238 239 240 241 |
void compute_descendants(int rid, int N){
Bag seen;
PQueue queue;
Stmt ins;
Stmt q;
bag_init(&seen);
| | | | | | | 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 |
void compute_descendants(int rid, int N){
Bag seen;
PQueue queue;
Stmt ins;
Stmt q;
bag_init(&seen);
pqueuex_init(&queue);
bag_insert(&seen, rid);
pqueuex_insert(&queue, rid, 0.0, 0);
db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)");
db_prepare(&q, "SELECT cid, mtime FROM plink WHERE pid=:rid");
while( (N--)>0 && (rid = pqueuex_extract(&queue, 0))!=0 ){
db_bind_int(&ins, ":rid", rid);
db_step(&ins);
db_reset(&ins);
db_bind_int(&q, ":rid", rid);
while( db_step(&q)==SQLITE_ROW ){
int pid = db_column_int(&q, 0);
double mtime = db_column_double(&q, 1);
if( bag_insert(&seen, pid) ){
pqueuex_insert(&queue, pid, mtime, 0);
}
}
db_reset(&q);
}
bag_clear(&seen);
pqueuex_clear(&queue);
db_finalize(&ins);
db_finalize(&q);
}
/*
** COMMAND: descendants*
**
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
375 376 377 378 379 380 381 | /* ** Flags for sbsWriteText() */ #define SBS_NEWLINE 0x0001 /* End with \n\000 */ #define SBS_PAD 0x0002 /* Pad output to width spaces */ /* | | > > > | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
/*
** Flags for sbsWriteText()
*/
#define SBS_NEWLINE 0x0001 /* End with \n\000 */
#define SBS_PAD 0x0002 /* Pad output to width spaces */
/*
** Write up to width characters of pLine into p->zLine[]. Translate tabs into
** spaces. Add a newline if SBS_NEWLINE is set. Translate HTML characters
** if SBS_HTML is set. Pad the rendering out width bytes if SBS_PAD is set.
**
** This comment contains multibyte unicode characters (ü, Æ, ð) in order
** to test the ability of the diff code to handle such characters.
*/
static void sbsWriteText(SbsLine *p, DLine *pLine, unsigned flags){
int n = pLine->h & LENGTH_MASK;
int i; /* Number of input characters consumed */
int j; /* Number of output characters generated */
int k; /* Cursor position */
int needEndSpan = 0;
|
| ︙ | ︙ | |||
431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
memcpy(&z[j], "&", 5);
j += 5;
}else if( c=='>' && p->escHtml ){
memcpy(&z[j], ">", 4);
j += 4;
}else{
z[j++] = c;
}
}
if( needEndSpan ){
memcpy(&z[j], "</span>", 7);
j += 7;
}
if( (flags & SBS_PAD)!=0 ){
| > | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
memcpy(&z[j], "&", 5);
j += 5;
}else if( c=='>' && p->escHtml ){
memcpy(&z[j], ">", 4);
j += 4;
}else{
z[j++] = c;
if( (c&0xc0)==0x80 ) k--;
}
}
if( needEndSpan ){
memcpy(&z[j], "</span>", 7);
j += 7;
}
if( (flags & SBS_PAD)!=0 ){
|
| ︙ | ︙ | |||
886 887 888 889 890 891 892 | int i, j; /* Loop counters */ int m, ma, mb;/* Number of lines to output */ int skip; /* Number of lines to skip */ int nChunk = 0; /* Number of chunks of diff output seen so far */ SbsLine s; /* Output line buffer */ memset(&s, 0, sizeof(s)); | | | 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 | int i, j; /* Loop counters */ int m, ma, mb;/* Number of lines to output */ int skip; /* Number of lines to skip */ int nChunk = 0; /* Number of chunks of diff output seen so far */ SbsLine s; /* Output line buffer */ memset(&s, 0, sizeof(s)); s.zLine = fossil_malloc( 15*width + 200 ); if( s.zLine==0 ) return; s.width = width; s.escHtml = escHtml; s.iStart = -1; s.iStart2 = 0; s.iEnd = -1; A = p->aFrom; |
| ︙ | ︙ | |||
1167 1168 1169 1170 1171 1172 1173 |
score = (iEX - iSX) - 0.05*skew - 0.05*dist;
if( score>bestScore ){
bestScore = score;
iSXb = iSX;
iSYb = iSY;
iEXb = iEX;
iEYb = iEY;
| | | 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 |
score = (iEX - iSX) - 0.05*skew - 0.05*dist;
if( score>bestScore ){
bestScore = score;
iSXb = iSX;
iSYb = iSY;
iEXb = iEX;
iEYb = iEY;
}else if( iEX>iEXp ){
iSXp = iSX;
iSYp = iSY;
iEXp = iEX;
iEYp = iEY;
}
}
if( iSXb==iEXb && (iE1-iS1)*(iE2-iS2)<400 ){
|
| ︙ | ︙ | |||
1801 1802 1803 1804 1805 1806 1807 |
const char *zUuidFile = db_column_text(&q, 2);
const char *zUuidParentFile = db_column_text(&q, 3);
const char *zDate = db_column_text(&q, 4);
const char *zUser = db_column_text(&q, 5);
if( webLabel ){
if (zUuidParentFile) {
zLabel = mprintf(
| | | | | | | | 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 |
const char *zUuidFile = db_column_text(&q, 2);
const char *zUuidParentFile = db_column_text(&q, 3);
const char *zDate = db_column_text(&q, 4);
const char *zUser = db_column_text(&q, 5);
if( webLabel ){
if (zUuidParentFile) {
zLabel = mprintf(
"<a href='%R/info/%s' %s>%.10s</a> "
"<a href='%R/fdiff?v1=%s&v2=%s' %s>d</a> "
"%s %13.13s",
zUuid, zInfoTarget, zUuid,
zUuidParentFile, zUuidFile, zDiffTarget,
zDate, zUser);
}else{
zLabel = mprintf(
"<a href='%R/info/%s' %s>%.10s</a> "
"%s %13.13s",
zUuid, zInfoTarget, zUuid,
zDate, zUser);
}
}else{
zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser);
}
p->nVers++;
p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
|
| ︙ | ︙ | |||
1854 1855 1856 1857 1858 1859 1860 |
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
iLimit = atoi(PD("limit","-1"));
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
fossil_redirect_home();
}
style_header("File Annotation");
if( P("filevers") ) annFlags |= ANN_FILE_VERS;
| | | 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 |
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
iLimit = atoi(PD("limit","-1"));
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
fossil_redirect_home();
}
style_header("File Annotation");
if( P("filevers") ) annFlags |= ANN_FILE_VERS;
annotate_file(&ann, P("filename"), fnid, mid, g.perm.Hyperlink, iLimit, annFlags);
if( P("log") ){
int i;
@ <h2>Versions analyzed:</h2>
@ <ol>
for(i=0; i<ann.nVers; i++){
@ <li><tt>%s(ann.azVers[i])</tt></li>
}
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
** 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
** deleted files to be displayed.
**
** Options:
** --brief Show filenames only
** --context|-c N Use N lines of context
** --from|-r VERSION select VERSION as source for the diff
** -i use internal diff logic
** --new-file|-N output complete text of added or deleted files
** --to VERSION select VERSION as target for the diff
** --side-by-side|-y side-by-side diff
** --width|-W N Width of lines in side-by-side diff
*/
void diff_cmd(void){
int isGDiff; /* True for gdiff. False for normal diff */
int isInternDiff; /* True for internal diff */
int hasNFlag; /* True if -N or --new-file flag is used */
const char *zFrom; /* Source version number */
const char *zTo; /* Target version number */
const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
int diffFlags = 0; /* Flags to control the DIFF */
int f;
isGDiff = g.argv[1][0]=='g';
isInternDiff = find_option("internal","i",0)!=0;
zFrom = find_option("from", "r", 1);
zTo = find_option("to", 0, 1);
diffFlags = diff_options();
hasNFlag = find_option("new-file","N",0)!=0;
if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
if( zTo==0 ){
db_must_be_within_tree();
verify_all_options();
if( !isInternDiff ){
zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
}
if( g.argc>=3 ){
| > > > > > > > > > > | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 |
** 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
** deleted files to be displayed.
**
** Options:
** --branch BRANCH Show diff of all changes on BRANCH
** --brief Show filenames only
** --context|-c N Use N lines of context
** --from|-r VERSION select VERSION as source for the diff
** -i use internal diff logic
** --new-file|-N output complete text of added or deleted files
** --to VERSION select VERSION as target for the diff
** --side-by-side|-y side-by-side diff
** --width|-W N Width of lines in side-by-side diff
*/
void diff_cmd(void){
int isGDiff; /* True for gdiff. False for normal diff */
int isInternDiff; /* True for internal diff */
int hasNFlag; /* True if -N or --new-file flag is used */
const char *zFrom; /* Source version number */
const char *zTo; /* Target version number */
const char *zBranch; /* Branch to diff */
const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
int diffFlags = 0; /* Flags to control the DIFF */
int f;
isGDiff = g.argv[1][0]=='g';
isInternDiff = find_option("internal","i",0)!=0;
zFrom = find_option("from", "r", 1);
zTo = find_option("to", 0, 1);
zBranch = find_option("branch", 0, 1);
diffFlags = diff_options();
hasNFlag = find_option("new-file","N",0)!=0;
if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
if( zBranch ){
if( zTo || zFrom ){
fossil_fatal("cannot use --from or --to with --branch");
}
zTo = zBranch;
zFrom = mprintf("root:%s", zBranch);
}
if( zTo==0 ){
db_must_be_within_tree();
verify_all_options();
if( !isInternDiff ){
zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
}
if( g.argc>=3 ){
|
| ︙ | ︙ | |||
546 547 548 549 550 551 552 |
diff_all_two_versions(zFrom, zTo, zDiffCmd, diffFlags);
}
}
}
/*
** WEBPAGE: vpatch
| | | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 |
diff_all_two_versions(zFrom, zTo, zDiffCmd, diffFlags);
}
}
}
/*
** WEBPAGE: vpatch
** URL vpatch?from=UUID&to=UUID
*/
void vpatch_page(void){
const char *zFrom = P("from");
const char *zTo = P("to");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
cgi_set_content_type("text/plain");
diff_all_two_versions(zFrom, zTo, 0, DIFF_NEWFILE);
}
|
Changes to src/event.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 |
#include "event.h"
/*
** Output a hyperlink to an event given its tagid.
*/
void hyperlink_to_event_tagid(int tagid){
char *zEventId;
| < < | < < < < < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include "event.h"
/*
** Output a hyperlink to an event given its tagid.
*/
void hyperlink_to_event_tagid(int tagid){
char *zEventId;
zEventId = db_text(0, "SELECT substr(tagname, 7) FROM tag WHERE tagid=%d",
tagid);
@ [%z(href("%R/event/%s",zEventId))%S(zEventId)</a>]
free(zEventId);
}
/*
** WEBPAGE: event
** URL: /event
** PARAMETERS:
|
| ︙ | ︙ | |||
128 129 130 131 132 133 134 |
if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
style_submenu_element("Edit", "Edit", "%s/eventedit?name=%s",
g.zTop, zEventId);
}
zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate);
style_submenu_element("Context", "Context", "%s/timeline?c=%T",
g.zTop, zETime);
| | | | | | | | | | | 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 |
if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
style_submenu_element("Edit", "Edit", "%s/eventedit?name=%s",
g.zTop, zEventId);
}
zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate);
style_submenu_element("Context", "Context", "%s/timeline?c=%T",
g.zTop, zETime);
if( g.perm.Hyperlink ){
if( showDetail ){
style_submenu_element("Plain", "Plain", "%s/event?name=%s&aid=%s",
g.zTop, zEventId, zUuid);
if( nextRid ){
char *zNext;
zNext = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nextRid);
style_submenu_element("Next", "Next",
"%s/event?name=%s&aid=%s&detail=1",
g.zTop, zEventId, zNext);
free(zNext);
}
if( prevRid ){
char *zPrev;
zPrev = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", prevRid);
style_submenu_element("Prev", "Prev",
"%s/event?name=%s&aid=%s&detail=1",
g.zTop, zEventId, zPrev);
free(zPrev);
}
}else{
style_submenu_element("Detail", "Detail",
"%s/event?name=%s&aid=%s&detail=1",
g.zTop, zEventId, zUuid);
}
}
if( showDetail && g.perm.Hyperlink ){
int i;
const char *zClr = 0;
Blob comment;
zATime = db_text(0, "SELECT datetime(%.17g)", pEvent->rDate);
@ <p>Event [%z(href("%R/artifact/%s",zUuid))%S(zUuid)</a>] at
@ [%z(href("%R/timeline?c=%T",zETime))%s(zETime)</a>]
@ entered by user <b>%h(pEvent->zUser)</b> on
@ [%z(href("%R/timeline?c=%T",zATime))%s(zATime)</a>]:</p>
@ <blockquote>
for(i=0; i<pEvent->nTag; i++){
if( fossil_strcmp(pEvent->aTag[i].zName,"+bgcolor")==0 ){
zClr = pEvent->aTag[i].zValue;
}
}
if( zClr && zClr[0]==0 ) zClr = 0;
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
303 304 305 306 307 308 309 |
@ <tr><td>
@ <div class="divider">%s(zPrevDate)</div>
@ </td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
@ <tr><td class="timelineTime">
| | < < < < < | | | | | 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 |
@ <tr><td>
@ <div class="divider">%s(zPrevDate)</div>
@ </td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
@ <tr><td class="timelineTime">
@ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td>
@ <td class="timelineGraph"><div id="m%d(gidx)"></div></td>
if( zBgClr && zBgClr[0] ){
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
}else{
@ <td class="timelineTableCell">
}
sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid);
sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin);
if( zUuid ){
@ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> part of check-in
}else{
@ <b>Deleted</b> by check-in
}
hyperlink_to_uuid(zShortCkin);
@ %h(zCom) (user:
hyperlink_to_user(zUser, zDate, "");
@ branch: %h(zBr))
if( g.perm.Hyperlink && zUuid ){
const char *z = zFilename;
if( fpid ){
@ %z(href("%R/fdiff?v1=%s&v2=%s",zPUuid,zUuid))[diff]</a>
}
@ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z))
@ [annotate]</a>
}
@ </td></tr>
}
db_finalize(&q);
if( pGraph ){
graph_finish(pGraph, 0);
|
| ︙ | ︙ |
Changes to src/glob.c.
| ︙ | ︙ | |||
108 109 110 111 112 113 114 |
if( zPatternList==0 || zPatternList[0]==0 ) return 0;
nList = strlen(zPatternList);
p = fossil_malloc( sizeof(*p) + nList+1 );
memset(p, 0, sizeof(*p));
z = (char*)&p[1];
memcpy(z, zPatternList, nList+1);
while( z[0] ){
| | > > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
if( zPatternList==0 || zPatternList[0]==0 ) return 0;
nList = strlen(zPatternList);
p = fossil_malloc( sizeof(*p) + nList+1 );
memset(p, 0, sizeof(*p));
z = (char*)&p[1];
memcpy(z, zPatternList, nList+1);
while( z[0] ){
while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ){
z++; /* Skip leading spaces and newlines */
}
if( z[0]=='\'' || z[0]=='"' ){
delimiter = z[0];
z++;
}else{
delimiter = ',';
}
if( z[0]==0 ) break;
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
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 |
if( zComment ){
fossil_print("comment: ");
comment_print(zComment, 14, 79);
free(zComment);
}
}
/*
** COMMAND: info
**
** Usage: %fossil info ?VERSION | REPOSITORY_FILENAME? ?OPTIONS?
**
** With no arguments, provide information about the current tree.
** If an argument is specified, provide information about the object
** in the respository of the current tree that the argument refers
** to. Or if the argument is the name of a repository, show
** information about that repository.
**
** Use the "finfo" command to get information about a specific
** file in a checkout.
**
** Options:
**
** -R|--repository FILE Extract info from repository FILE
**
** See also: annotate, artifact, finfo, timeline
*/
void info_cmd(void){
i64 fsize;
if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){
db_open_config(0);
db_record_repository_filename(g.argv[2]);
db_open_repository(g.argv[2]);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
fossil_print("project-code: %s\n", db_get("project-code", "<none>"));
return;
}
db_find_and_open_repository(0,0);
if( g.argc==2 ){
int vid;
/* 012345678901234 */
db_record_repository_filename(0);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
if( g.localOpen ){
fossil_print("repository: %s\n", db_repository_filename());
fossil_print("local-root: %s\n", g.zLocalRoot);
}
#if defined(_WIN32)
if( g.zHome ){
fossil_print("user-home: %s\n", g.zHome);
}
#endif
fossil_print("project-code: %s\n", db_get("project-code", ""));
vid = g.localOpen ? db_lget_int("checkout", 0) : 0;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
if( zComment ){
fossil_print("comment: ");
comment_print(zComment, 14, 79);
free(zComment);
}
}
/*
** Print information about the URLs used to access a repository and
** checkouts in a repository.
*/
static void extraRepoInfo(void){
Stmt s;
db_prepare(&s, "SELECT substr(name,7), date(mtime,'unixepoch')"
" FROM config"
" WHERE name GLOB 'ckout:*' ORDER BY name");
while( db_step(&s)==SQLITE_ROW ){
const char *zName;
const char *zCkout = db_column_text(&s, 0);
if( g.localOpen ){
if( fossil_strcmp(zCkout, g.zLocalRoot)==0 ) continue;
zName = "alt-root:";
}else{
zName = "check-out:";
}
fossil_print("%-11s %-54s %s\n", zName, zCkout,
db_column_text(&s, 1));
}
db_finalize(&s);
db_prepare(&s, "SELECT substr(name,9), date(mtime,'unixepoch')"
" FROM config"
" WHERE name GLOB 'baseurl:*' ORDER BY name");
while( db_step(&s)==SQLITE_ROW ){
fossil_print("access-url: %-54s %s\n", db_column_text(&s, 0),
db_column_text(&s, 1));
}
db_finalize(&s);
}
/*
** COMMAND: info
**
** Usage: %fossil info ?VERSION | REPOSITORY_FILENAME? ?OPTIONS?
**
** With no arguments, provide information about the current tree.
** If an argument is specified, provide information about the object
** in the respository of the current tree that the argument refers
** to. Or if the argument is the name of a repository, show
** information about that repository.
**
** Use the "finfo" command to get information about a specific
** file in a checkout.
**
** Options:
**
** -R|--repository FILE Extract info from repository FILE
** -l|--detail Show extra information
**
** See also: annotate, artifact, finfo, timeline
*/
void info_cmd(void){
i64 fsize;
int bDetail = find_option("detail","l",0)!=0;
if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){
db_open_config(0);
db_record_repository_filename(g.argv[2]);
db_open_repository(g.argv[2]);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
fossil_print("project-code: %s\n", db_get("project-code", "<none>"));
extraRepoInfo();
return;
}
db_find_and_open_repository(0,0);
if( g.argc==2 ){
int vid;
/* 012345678901234 */
db_record_repository_filename(0);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
if( g.localOpen ){
fossil_print("repository: %s\n", db_repository_filename());
fossil_print("local-root: %s\n", g.zLocalRoot);
}
if( bDetail ) extraRepoInfo();
#if defined(_WIN32)
if( g.zHome ){
fossil_print("user-home: %s\n", g.zHome);
}
#endif
fossil_print("project-code: %s\n", db_get("project-code", ""));
vid = g.localOpen ? db_lget_int("checkout", 0) : 0;
|
| ︙ | ︙ | |||
225 226 227 228 229 230 231 |
hyperlink_to_uuid(zOrigUuid);
}else{
@ propagates to descendants
}
#if 0
if( zValue && fossil_strcmp(zTagname,"branch")==0 ){
@
| | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
hyperlink_to_uuid(zOrigUuid);
}else{
@ propagates to descendants
}
#if 0
if( zValue && fossil_strcmp(zTagname,"branch")==0 ){
@
@ %z(href("%R/timeline?r=%T",zValue))branch timeline</a>
}
#endif
}
if( zSrcUuid && zSrcUuid[0] ){
if( tagtype==0 ){
@ by
}else{
|
| ︙ | ︙ | |||
297 298 299 300 301 302 303 |
const char *zName, /* Name of the file that has changed */
const char *zOld, /* blob.uuid before change. NULL for added files */
const char *zNew, /* blob.uuid after change. NULL for deletes */
const char *zOldName, /* Prior name. NULL if no name change. */
int diffFlags, /* Flags for text_diff(). Zero to omit diffs */
int mperm /* executable or symlink permission for zNew */
){
| | | | | | | | | | | | | | 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 |
const char *zName, /* Name of the file that has changed */
const char *zOld, /* blob.uuid before change. NULL for added files */
const char *zNew, /* blob.uuid after change. NULL for deletes */
const char *zOldName, /* Prior name. NULL if no name change. */
int diffFlags, /* Flags for text_diff(). Zero to omit diffs */
int mperm /* executable or symlink permission for zNew */
){
if( !g.perm.Hyperlink ){
if( zNew==0 ){
@ <p>Deleted %h(zName)</p>
}else if( zOld==0 ){
@ <p>Added %h(zName)</p>
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
@ <p>Name change from %h(zOldName) to %h(zName)
}else if( fossil_strcmp(zNew, zOld)==0 ){
@ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared")
@ for %h(zName)</p>
}else{
@ <p>Changes to %h(zName)</p>
}
if( diffFlags ){
@ <pre style="white-space:pre;">
append_diff(zOld, zNew, diffFlags);
@ </pre>
}
}else{
if( zOld && zNew ){
if( fossil_strcmp(zOld, zNew)!=0 ){
@ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@ from %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a>
@ to %z(href("%R/artifact/%s",zNew))[%S(zNew)].</a>
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
@ <p>Name change from
@ from %z(href("%R/finfo?name=%T",zOldName))%h(zOldName)</a>
@ to %z(href("%R/finfo?name=%T",zName))%h(zName)</a>.
}else{
@ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for
@ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
}
}else if( zOld ){
@ <p>Deleted %z(href("%s/finfo?name=%T",g.zTop,zName))%h(zName)</a>
@ version %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a>
}else{
@ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
}
if( diffFlags ){
@ <pre style="white-space:pre;">
append_diff(zOld, zNew, diffFlags);
@ </pre>
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
@
@ %z(href("%R/fdiff?v1=%S&v2=%S",zOld,zNew))[diff]</a>
}
@ </p>
}
}
/*
** Construct an appropriate diffFlag for text_diff() based on query
|
| ︙ | ︙ | |||
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
const char *zUuid = db_column_text(&q, 0);
char *zTitle = mprintf("Check-in [%.10s]", zUuid);
char *zEUser, *zEComment;
const char *zUser;
const char *zComment;
const char *zDate;
const char *zOrigDate;
style_header(zTitle);
login_anonymous_available();
free(zTitle);
zEUser = db_text(0,
"SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_USER, rid);
zEComment = db_text(0,
"SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_COMMENT, rid);
zUser = db_column_text(&q, 2);
zComment = db_column_text(&q, 3);
zDate = db_column_text(&q,1);
zOrigDate = db_column_text(&q, 4);
@ <div class="section">Overview</div>
@ <table class="label-value">
@ <tr><th>SHA1 Hash:</th><td>%s(zUuid)
| > > > > | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
const char *zUuid = db_column_text(&q, 0);
char *zTitle = mprintf("Check-in [%.10s]", zUuid);
char *zEUser, *zEComment;
const char *zUser;
const char *zComment;
const char *zDate;
const char *zOrigDate;
const char *zBranch;
style_header(zTitle);
login_anonymous_available();
free(zTitle);
zEUser = db_text(0,
"SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_USER, rid);
zEComment = db_text(0,
"SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_COMMENT, rid);
zBranch = db_text("trunk",
"SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_BRANCH, rid);
zUser = db_column_text(&q, 2);
zComment = db_column_text(&q, 3);
zDate = db_column_text(&q,1);
zOrigDate = db_column_text(&q, 4);
@ <div class="section">Overview</div>
@ <table class="label-value">
@ <tr><th>SHA1 Hash:</th><td>%s(zUuid)
|
| ︙ | ︙ | |||
500 501 502 503 504 505 506 |
const char *zDate = db_column_text(&q, 2);
if( zUser==0 || zUser[0]==0 ) zUser = "unknown";
@ <tr><th>Received From:</th>
@ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
}
db_finalize(&q);
}
| | | | | | | < < < < | | > > | | > > > > > > > > > > > > > | | | | | | | | | | | | | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
const char *zDate = db_column_text(&q, 2);
if( zUser==0 || zUser[0]==0 ) zUser = "unknown";
@ <tr><th>Received From:</th>
@ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
}
db_finalize(&q);
}
if( g.perm.Hyperlink ){
const char *zProjName = db_get("project-name", "unnamed");
@ <tr><th>Timelines:</th><td>
@ %z(href("%R/timeline?f=%S",zUuid))family</a>
if( zParent ){
@ | %z(href("%R/timeline?p=%S",zUuid))ancestors</a>
}
if( !isLeaf ){
@ | %z(href("%R/timeline?d=%S",zUuid))descendants</a>
}
if( zParent && !isLeaf ){
@ | %z(href("%R/timeline?dp=%S",zUuid))both</a>
}
db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
" WHERE rid=%d AND tagtype>0 "
" AND tag.tagid=tagxref.tagid "
" AND +tag.tagname GLOB 'sym-*'", rid);
while( db_step(&q)==SQLITE_ROW ){
const char *zTagName = db_column_text(&q, 0);
@ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
}
db_finalize(&q);
if( g.perm.Zip ){
char *zUrl = mprintf("%R/tarball/%s-%S.tar.gz?uuid=%s",
zProjName, zUuid, zUuid);
@ </td></tr>
@ <tr><th>Downloads:</th><td>
@ %z(href("%s",zUrl))Tarball</a>
@ | %z(href("%R/zip/%s-%S.zip?uuid=%s",zProjName,zUuid,zUuid))
@ ZIP archive</a>
fossil_free(zUrl);
}
#if 0
if( isLeaf && fossil_strcmp(zBranch,"trunk")!=0 ){
@ </td></tr>
@ <tr><th>Diffs:</th><td>
@ %z(href("%R/vdiff?branch=%t",zBranch))Changes in %h(zBranch)</a>
@ | %z(href("%R/vdiff?from=trunk&to=%t",zBranch))Changes
@ from trunk</a>
}
#endif
@ </td></tr>
@ <tr><th>Other Links:</th>
@ <td>
@ %z(href("%R/dir?ci=%S",zUuid))files</a>
@ | %z(href("%R/artifact/%S",zUuid))manifest</a>
@ | <a href="%s(g.zTop)/vdiff?from=pbranch:%S(zUuid)&to=%S(zUuid)">
@ vdiff to parent branch</a>
if( g.perm.Write ){
@ | %z(href("%R/ci_edit?r=%S",zUuid))edit</a>
}
@ </td>
@ </tr>
}
@ </table>
}else{
style_header("Check-in Information");
login_anonymous_available();
}
db_finalize(&q);
showTags(rid, "");
if( zParent ){
@ <div class="section">Changes</div>
@ <div class="sectionmenu">
showDiff = g.zPath[0]!='c';
if( db_get_boolean("show-version-diffs", 0)==0 ){
showDiff = !showDiff;
if( showDiff ){
@ %z(xhref("class='button'","%R/vinfo/%T",zName))
@ hide diffs</a>
if( sideBySide ){
@ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName))
@ unified diffs</a>
}else{
@ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName))
@ side-by-side diffs</a>
}
}else{
@ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName))
@ show unified diffs</a>
@ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName))
@ show side-by-side diffs</a>
}
}else{
if( showDiff ){
@ %z(xhref("class='button'","%R/ci/%T",zName))hide diffs</a>
if( sideBySide ){
@ %z(xhref("class='button'","%R/info/%T?sbs=0",zName))
@ unified diffs</a>
}else{
@ %z(xhref("class='button'","%R/info/%T?sbs=1",zName))
@ side-by-side diffs</a>
}
}else{
@ %z(xhref("class='button'","%R/vinfo/%T?sbs=0",zName))
@ show unified diffs</a>
@ %z(xhref("class='button'","%R/vinfo/%T?sbs=1",zName))
@ show side-by-side diffs</a>
}
}
@ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid))
@ patch</a></div>
db_prepare(&q,
"SELECT name,"
" mperm,"
" (SELECT uuid FROM blob WHERE rid=mlink.pid),"
" (SELECT uuid FROM blob WHERE rid=mlink.fid),"
" (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)"
|
| ︙ | ︙ | |||
665 666 667 668 669 670 671 |
@ <tr><th>Date:</th><td>
hyperlink_to_date(zDate, "</td></tr>");
if( g.perm.Setup ){
@ <tr><th>Record ID:</th><td>%d(rid)</td></tr>
}
@ <tr><th>Original User:</th><td>
hyperlink_to_user(zUser, zDate, "</td></tr>");
| | | | | 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
@ <tr><th>Date:</th><td>
hyperlink_to_date(zDate, "</td></tr>");
if( g.perm.Setup ){
@ <tr><th>Record ID:</th><td>%d(rid)</td></tr>
}
@ <tr><th>Original User:</th><td>
hyperlink_to_user(zUser, zDate, "</td></tr>");
if( g.perm.Hyperlink ){
@ <tr><th>Commands:</th>
@ <td>
@ %z(href("%R/whistory?name=%t",zName))history</a>
@ | %z(href("%R/artifact/%S",zUuid))raw-text</a>
@ </td>
@ </tr>
}
@ </table></p>
}else{
style_header("Wiki Information");
rid = 0;
|
| ︙ | ︙ | |||
719 720 721 722 723 724 725 |
** manifest. Return the number of errors.
*/
static Manifest *vdiff_parse_manifest(const char *zParam, int *pRid){
int rid;
*pRid = rid = name_to_rid_www(zParam);
if( rid==0 ){
| > > | > > > | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 |
** manifest. Return the number of errors.
*/
static Manifest *vdiff_parse_manifest(const char *zParam, int *pRid){
int rid;
*pRid = rid = name_to_rid_www(zParam);
if( rid==0 ){
const char *z = P(zParam);
if( z==0 || z[0]==0 ){
webpage_error("Missing \"%s\" query parameter.", zParam);
}else{
webpage_error("No such artifact: \"%s\"", z);
}
return 0;
}
if( !is_a_version(rid) ){
webpage_error("Artifact %s is not a checkin.", P(zParam));
return 0;
}
return manifest_get(rid, CFTYPE_MANIFEST);
|
| ︙ | ︙ | |||
763 764 765 766 767 768 769 | } db_finalize(&q); } /* ** WEBPAGE: vdiff | | > > > > > > | | | | | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 |
}
db_finalize(&q);
}
/*
** WEBPAGE: vdiff
** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN;sbs=BOOLEAN
**
** Show all differences between two checkins.
*/
void vdiff_page(void){
int ridFrom, ridTo;
int showDetail = 0;
int sideBySide = 0;
int diffFlags = 0;
Manifest *pFrom, *pTo;
ManifestFile *pFileFrom, *pFileTo;
const char *zBranch;
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
login_anonymous_available();
zBranch = P("branch");
if( zBranch && zBranch[0] ){
cgi_replace_parameter("from", mprintf("root:%s", zBranch));
cgi_replace_parameter("to", zBranch);
}
pTo = vdiff_parse_manifest("to", &ridTo);
if( pTo==0 ) return;
pFrom = vdiff_parse_manifest("from", &ridFrom);
if( pFrom==0 ) return;
sideBySide = atoi(PD("sbs","1"));
showDetail = atoi(PD("detail","0"));
if( !showDetail && sideBySide ) showDetail = 1;
if (showDetail){
style_submenu_element("Abstract", "abstract",
"%s/vdiff?from=%T&to=%T&detail=0&sbs=0",
g.zTop, P("from"), P("to"));
|
| ︙ | ︙ | |||
916 917 918 919 920 921 922 |
if( mPerm==PERM_LNK ){
@ <li>Symbolic link
}else if( mPerm==PERM_EXE ){
@ <li>Executable file
}else{
@ <li>File
}
| < | < < < < < < | | < | < | | | 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 |
if( mPerm==PERM_LNK ){
@ <li>Symbolic link
}else if( mPerm==PERM_EXE ){
@ <li>Executable file
}else{
@ <li>File
}
@ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@ <ul>
prevName = fossil_strdup(zName);
}
@ <li>
hyperlink_to_date(zDate,"");
@ - part of checkin
hyperlink_to_uuid(zVers);
if( zBr && zBr[0] ){
@ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a>
}
@ - %w(zCom) (user:
hyperlink_to_user(zUser,zDate,")");
if( g.perm.Hyperlink ){
@ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName))
@ [annotate]</a>
}
cnt++;
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_append(pDownloadName, zName, -1);
}
}
|
| ︙ | ︙ | |||
969 970 971 972 973 974 975 |
const char *zDate = db_column_text(&q, 1);
const char *zUser = db_column_text(&q, 2);
if( cnt>0 ){
@ Also wiki page
}else{
@ Wiki page
}
| < < < | < < | 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 |
const char *zDate = db_column_text(&q, 1);
const char *zUser = db_column_text(&q, 2);
if( cnt>0 ){
@ Also wiki page
}else{
@ Wiki page
}
@ [%z(href("%R/wiki?name=%t",zPagename))%h(zPagename)</a>] by
hyperlink_to_user(zUser,zDate," on");
hyperlink_to_date(zDate,".");
nWiki++;
cnt++;
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_appendf(pDownloadName, "%s.wiki", zPagename);
}
|
| ︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 |
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
| | | | | | | | 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 |
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
if( g.perm.Hyperlink && g.perm.RdTkt ){
@ ticket [%z(href("%R/tktview?name=%S",zTarget))%S(zTarget)</a>]
}else{
@ ticket [%S(zTarget)]
}
}else{
if( g.perm.Hyperlink && g.perm.RdWiki ){
@ wiki page [%z(href("%R/wiki?name=%t",zTarget)))%h(zTarget)</a>]
}else{
@ wiki page [%h(zTarget)]
}
}
@ added by
hyperlink_to_user(zUser,zDate," on");
hyperlink_to_date(zDate,".");
cnt++;
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_append(pDownloadName, zFilename, -1);
}
}
db_finalize(&q);
if( cnt==0 ){
@ Control artifact.
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_appendf(pDownloadName, "%.10s.txt", zUuid);
}
}else if( linkToView && g.perm.Hyperlink ){
@ %z(href("%R/artifact/%S",zUuid))[view]</a>
}
}
/*
** WEBPAGE: fdiff
** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN
|
| ︙ | ︙ | |||
1140 1141 1142 1143 1144 1145 1146 |
style_submenu_element("Unified Diff", "udiff",
"%s/fdiff?v1=%T&v2=%T&sbs=0",
g.zTop, P("v1"), P("v2"));
}
if( P("smhdr")!=0 ){
@ <h2>Differences From Artifact
| | | | | < | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 |
style_submenu_element("Unified Diff", "udiff",
"%s/fdiff?v1=%T&v2=%T&sbs=0",
g.zTop, P("v1"), P("v2"));
}
if( P("smhdr")!=0 ){
@ <h2>Differences From Artifact
@ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
@ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
}else{
@ <h2>Differences From
@ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
object_description(v1, 0, 0);
@ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
object_description(v2, 0, 0);
}
@ <hr />
@ <div class="%s(zStyle)">
@ %s(blob_str(&diff))
@ </div>
blob_reset(&diff);
|
| ︙ | ︙ | |||
1252 1253 1254 1255 1256 1257 1258 |
rid = name_to_rid_www("name");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 |
rid = name_to_rid_www("name");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
style_header("Hex Artifact Content");
|
| ︙ | ︙ | |||
1355 1356 1357 1358 1359 1360 1361 |
else cgi_append_content("\n", 1);
z += i;
if( z[0]=='\n' ) z++;
}
if( n<iEnd ) cgi_printf("</div>");
@ </pre>
if( iStart ){
| < < | < < | 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 |
else cgi_append_content("\n", 1);
z += i;
if( z[0]=='\n' ) z++;
}
if( n<iEnd ) cgi_printf("</div>");
@ </pre>
if( iStart ){
@ <script>gebi('topln').scrollIntoView(true);</script>
}
}
/*
** WEBPAGE: artifact
** URL: /artifact/ARTIFACTID
|
| ︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
style_header("Artifact Content");
|
| ︙ | ︙ | |||
1458 1459 1460 1461 1462 1463 1464 |
output_text_with_line_numbers(z, zLn);
}else{
@ <pre>
@ %h(z)
@ </pre>
}
}else if( strncmp(zMime, "image/", 6)==0 ){
| | | 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 |
output_text_with_line_numbers(z, zLn);
}else{
@ <pre>
@ %h(z)
@ </pre>
}
}else if( strncmp(zMime, "image/", 6)==0 ){
@ <img src="%s(g.zTop)/raw?name=%s(zUuid)&m=%s(zMime)"></img>
}else{
@ <i>(file is %d(blob_size(&content)) bytes of binary data)</i>
}
@ </blockquote>
}
style_footer();
}
|
| ︙ | ︙ | |||
1487 1488 1489 1490 1491 1492 1493 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | | | | < | 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
pTktChng = manifest_get(rid, CFTYPE_TICKET);
if( pTktChng==0 ){
fossil_redirect_home();
}
style_header("Ticket Change Details");
zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
memcpy(zTktName, pTktChng->zTicketUuid, 10);
zTktName[10] = 0;
if( g.perm.Hyperlink ){
@ <h2>Changes to ticket
@ %z(href("%R/tktview/%s",pTktChng->zTicketUuid)))%s(zTktName)</a></h2>
@
@ <p>By %h(pTktChng->zUser) on %s(zDate). See also:
@ %z(href("%R/artifact/%T",zUuid))artifact content</a>, and
@ %z(href("%R/tkthistory/%s",pTktChng->zTicketUuid))ticket history</a></p>
}else{
@ <h2>Changes to ticket %s(zTktName)</h2>
@
@ <p>By %h(pTktChng->zUser) on %s(zDate).
@ </p>
}
@
|
| ︙ | ︙ | |||
1663 1664 1665 1666 1667 1668 1669 |
};
int nColor = sizeof(aColor)/sizeof(aColor[0])-1;
int stdClrFound = 0;
int i;
@ <table border="0" cellpadding="0" cellspacing="1">
if( zIdPropagate ){
| | | | 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 |
};
int nColor = sizeof(aColor)/sizeof(aColor[0])-1;
int stdClrFound = 0;
int i;
@ <table border="0" cellpadding="0" cellspacing="1">
if( zIdPropagate ){
@ <tr><td colspan="6" align="left"><label>
if( fPropagate ){
@ <input type="checkbox" name="%s(zIdPropagate)" checked="checked" />
}else{
@ <input type="checkbox" name="%s(zIdPropagate)" />
}
@ Propagate color to descendants</label></td></tr>
}
@ <tr>
for(i=0; i<nColor; i++){
const char *zClr = aColor[i].zColor;
if( zClr==0 ) zClr = aColor[i].zCName;
if( zClr[0] ){
@ <td style="background-color: %h(zClr);">
|
| ︙ | ︙ | |||
1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 |
const char *zNewTagFlag;
const char *zNewTag;
const char *zNewBrFlag;
const char *zNewBranch;
const char *zCloseFlag;
int fPropagateColor; /* True if color propagates before edit */
int fNewPropagateColor; /* True if color propagates after edit */
char *zUuid;
Blob comment;
Stmt q;
login_check_credentials();
if( !g.perm.Write ){ login_needed(); return; }
rid = name_to_typed_rid(P("r"), "ci");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
" FROM event WHERE objid=%d", rid);
if( zComment==0 ) fossil_redirect_home();
if( P("cancel") ){
cgi_redirectf("ci?name=%s", zUuid);
}
zNewComment = PD("c",zComment);
zUser = db_text(0, "SELECT coalesce(euser,user)"
" FROM event WHERE objid=%d", rid);
if( zUser==0 ) fossil_redirect_home();
zNewUser = PDT("u",zUser);
zDate = db_text(0, "SELECT datetime(mtime)"
" FROM event WHERE objid=%d", rid);
| > > | 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 |
const char *zNewTagFlag;
const char *zNewTag;
const char *zNewBrFlag;
const char *zNewBranch;
const char *zCloseFlag;
int fPropagateColor; /* True if color propagates before edit */
int fNewPropagateColor; /* True if color propagates after edit */
const char *zChngTime = 0; /* Value of chngtime= query param, if any */
char *zUuid;
Blob comment;
Stmt q;
login_check_credentials();
if( !g.perm.Write ){ login_needed(); return; }
rid = name_to_typed_rid(P("r"), "ci");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
" FROM event WHERE objid=%d", rid);
if( zComment==0 ) fossil_redirect_home();
if( P("cancel") ){
cgi_redirectf("ci?name=%s", zUuid);
}
if( g.perm.Setup ) zChngTime = P("chngtime");
zNewComment = PD("c",zComment);
zUser = db_text(0, "SELECT coalesce(euser,user)"
" FROM event WHERE objid=%d", rid);
if( zUser==0 ) fossil_redirect_home();
zNewUser = PDT("u",zUser);
zDate = db_text(0, "SELECT datetime(mtime)"
" FROM event WHERE objid=%d", rid);
|
| ︙ | ︙ | |||
1814 1815 1816 1817 1818 1819 1820 |
if( P("apply") ){
Blob ctrl;
char *zNow;
int nChng = 0;
login_verify_csrf_secret();
blob_zero(&ctrl);
| | | 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 |
if( P("apply") ){
Blob ctrl;
char *zNow;
int nChng = 0;
login_verify_csrf_secret();
blob_zero(&ctrl);
zNow = date_in_standard_format(zChngTime ? zChngTime : "now");
blob_appendf(&ctrl, "D %s\n", zNow);
db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
if( zNewColor[0]
&& (fPropagateColor!=fNewPropagateColor
|| fossil_strcmp(zColor,zNewColor)!=0)
){
char *zPrefix = "+";
|
| ︙ | ︙ | |||
1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 |
}
nTag++;
}
db_finalize(&q);
blob_appendf(&suffix, ")");
@ %s(blob_str(&suffix))
@ </td></tr></table>
@ </blockquote>
@ <hr />
blob_reset(&suffix);
}
@ <p>Make changes to attributes of check-in
| > > > > | > > > > > > > | | | > > | | | | | | | > | | | 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 |
}
nTag++;
}
db_finalize(&q);
blob_appendf(&suffix, ")");
@ %s(blob_str(&suffix))
@ </td></tr></table>
if( zChngTime ){
@ <p>The timestamp on the tag used to make the changes above
@ will be overridden as: %s(date_in_standard_format(zChngTime))</p>
}
@ </blockquote>
@ <hr />
blob_reset(&suffix);
}
@ <p>Make changes to attributes of check-in
@ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p>
@ <form action="%s(g.zTop)/ci_edit" method="post"><div>
login_insert_csrf_secret();
@ <input type="hidden" name="r" value="%S(zUuid)" />
@ <table border="0" cellspacing="10">
@ <tr><td align="right" valign="top"><b>User:</b></td>
@ <td valign="top">
@ <input type="text" name="u" size="20" value="%h(zNewUser)" />
@ </td></tr>
@ <tr><td align="right" valign="top"><b>Comment:</b></td>
@ <td valign="top">
@ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
@ </td></tr>
@ <tr><td align="right" valign="top"><b>Check-in Time:</b></td>
@ <td valign="top">
@ <input type="text" name="dt" size="20" value="%h(zNewDate)" />
@ </td></tr>
if( zChngTime ){
@ <tr><td align="right" valign="top"><b>Timestamp of this change:</b></td>
@ <td valign="top">
@ <input type="text" name="chngtime" size="20" value="%h(zChngTime)" />
@ </td></tr>
}
@ <tr><td align="right" valign="top"><b>Background Color:</b></td>
@ <td valign="top">
render_color_chooser(fNewPropagateColor, zNewColor, "pclr", "clr", "clrcust");
@ </td></tr>
@ <tr><td align="right" valign="top"><b>Tags:</b></td>
@ <td valign="top">
@ <label><input type="checkbox" id="newtag" name="newtag"%s(zNewTagFlag) />
@ Add the following new tag name to this check-in:</label>
@ <input type="text" style="width:15;" name="tagname" value="%h(zNewTag)"
@ onkeyup="gebi('newtag').checked=!!this.value" />
db_prepare(&q,
"SELECT tag.tagid, tagname FROM tagxref, tag"
" WHERE tagxref.rid=%d AND tagtype>0 AND tagxref.tagid=tag.tagid"
" ORDER BY CASE WHEN tagname GLOB 'sym-*' THEN substr(tagname,5)"
" ELSE tagname END /*sort*/",
rid
);
while( db_step(&q)==SQLITE_ROW ){
int tagid = db_column_int(&q, 0);
const char *zTagName = db_column_text(&q, 1);
char zLabel[30];
sqlite3_snprintf(sizeof(zLabel), zLabel, "c%d", tagid);
@ <br /><label>
if( P(zLabel) ){
@ <input type="checkbox" name="c%d(tagid)" checked="checked" />
}else{
@ <input type="checkbox" name="c%d(tagid)" />
}
if( strncmp(zTagName, "sym-", 4)==0 ){
@ Cancel tag <b>%h(&zTagName[4])</b></label>
}else{
@ Cancel special tag <b>%h(zTagName)</b></label>
}
}
db_finalize(&q);
@ </td></tr>
@ <tr><td align="right" valign="top"><b>Branching:</b></td>
@ <td valign="top">
@ <label><input id="newbr" type="checkbox" name="newbr"%s(zNewBrFlag) />
@ Make this check-in the start of a new branch named:</label>
@ <input type="text" style="width:15;" name="brname" value="%h(zNewBranch)"
@ onkeyup="gebi('newbr').checked=!!this.value" />
@ </td></tr>
if( is_a_leaf(rid)
&& !db_exists("SELECT 1 FROM tagxref "
" WHERE tagid=%d AND rid=%d AND tagtype>0",
TAG_CLOSED, rid)
){
@ <tr><td align="right" valign="top"><b>Leaf Closure:</b></td>
@ <td valign="top">
@ <label><input type="checkbox" name="close"%s(zCloseFlag) />
@ Mark this leaf as "closed" so that it no longer appears on the
@ "leaves" page and is no longer labeled as a "<b>Leaf</b>".</label>
@ </td></tr>
}
@ <tr><td colspan="2">
@ <input type="submit" name="preview" value="Preview" />
@ <input type="submit" name="apply" value="Apply Changes" />
@ <input type="submit" name="cancel" value="Cancel" />
@ </td></tr>
@ </table>
@ </div></form>
style_footer();
}
|
Changes to src/json.c.
| ︙ | ︙ | |||
173 174 175 176 177 178 179 | #else #define BEGIN_TIMER #define END_TIMER 0.0 #define HAS_TIMER 0 #endif | | > > | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
#else
#define BEGIN_TIMER
#define END_TIMER 0.0
#define HAS_TIMER 0
#endif
/*
** Returns true (non-0) if fossil appears to be running in JSON mode.
*/
char fossil_has_json(){
return g.json.isJsonMode && (g.isHTTP || g.json.post.o);
}
/*
** Placeholder /json/XXX page impl for NYI (Not Yet Implemented)
** (but planned) pages/commands.
|
| ︙ | ︙ | |||
465 466 467 468 469 470 471 |
**
** If it finds a value and that value is-a JSON number or is a string
** which looks like an integer or is-a JSON bool/null then it is
** converted to an int. If none of those apply then dflt is returned.
*/
int json_getenv_int(char const * pKey, int dflt ){
cson_value const * v = json_getenv(pKey);
| | | | > | | | | | > | | | | | < | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
**
** If it finds a value and that value is-a JSON number or is a string
** which looks like an integer or is-a JSON bool/null then it is
** converted to an int. If none of those apply then dflt is returned.
*/
int json_getenv_int(char const * pKey, int dflt ){
cson_value const * v = json_getenv(pKey);
const cson_type_id type = v ? cson_value_type_id(v) : CSON_TYPE_UNDEF;
switch(type){
case CSON_TYPE_INTEGER:
case CSON_TYPE_DOUBLE:
return (int)cson_value_get_integer(v);
case CSON_TYPE_STRING: {
char const * sv = cson_string_cstr(cson_value_get_string(v));
assert( (NULL!=sv) && "This is quite unexpected." );
return sv ? atoi(sv) : dflt;
}
case CSON_TYPE_BOOL:
return cson_value_get_bool(v) ? 1 : 0;
case CSON_TYPE_NULL:
return 0;
default:
return dflt;
}
}
/*
** Wrapper around json_getenv() which tries to evaluate a payload/env
** value as a boolean. Uses mostly the same logic as
|
| ︙ | ︙ | |||
501 502 503 504 505 506 507 |
** either 0 or 1, as opposed to "0 or non-zero", so that clients can
** pass a different value as dflt. Thus they can use, e.g. -1 to know
** whether or not this function found a match (it will return -1 in
** that case).
*/
char json_getenv_bool(char const * pKey, char dflt ){
cson_value const * v = json_getenv(pKey);
| | | | > | | | > | | | | | | | | | > | | | | | | | 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 |
** either 0 or 1, as opposed to "0 or non-zero", so that clients can
** pass a different value as dflt. Thus they can use, e.g. -1 to know
** whether or not this function found a match (it will return -1 in
** that case).
*/
char json_getenv_bool(char const * pKey, char dflt ){
cson_value const * v = json_getenv(pKey);
const cson_type_id type = v ? cson_value_type_id(v) : CSON_TYPE_UNDEF;
switch(type){
case CSON_TYPE_INTEGER:
case CSON_TYPE_DOUBLE:
return cson_value_get_integer(v) ? 1 : 0;
case CSON_TYPE_STRING: {
char const * sv = cson_string_cstr(cson_value_get_string(v));
assert( (NULL!=sv) && "This is quite unexpected." );
if(!*sv || ('0'==*sv)){
return 0;
}else{
return ((('1'<=*sv) && ('9'>=*sv))
|| ('t'==*sv) || ('T'==*sv)
|| ('y'==*sv) || ('Y'==*sv)
)
? 1 : 0;
}
}
case CSON_TYPE_BOOL:
return cson_value_get_bool(v) ? 1 : 0;
case CSON_TYPE_NULL:
return 0;
default:
return dflt;
}
}
/*
** Returns the string form of a json_getenv() value, but ONLY If that
** value is-a String. Non-strings are not converted to strings for
** this purpose. Returned memory is owned by g.json or fossil and is
|
| ︙ | ︙ | |||
753 754 755 756 757 758 759 |
g.json.authToken = json_getenv(FossilJsonKeys.authToken);
if(g.json.authToken
&& cson_value_is_string(g.json.authToken)
&& !PD(login_cookie_name(),NULL)){
/* tell fossil to use this login info.
FIXME?: because the JSON bits don't carry around
| | | | | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 |
g.json.authToken = json_getenv(FossilJsonKeys.authToken);
if(g.json.authToken
&& cson_value_is_string(g.json.authToken)
&& !PD(login_cookie_name(),NULL)){
/* tell fossil to use this login info.
FIXME?: because the JSON bits don't carry around
login_cookie_name(), there is(?) a potential(?) login hijacking
window here. We may need to change the JSON auth token to be in
the form: login_cookie_name()=...
Then again, the hardened cookie value helps ensure that
only a proper key/value match is valid.
*/
cgi_replace_parameter( login_cookie_name(), cson_value_get_cstr(g.json.authToken) );
}else if( g.isHTTP ){
/* try fossil's conventional cookie. */
|
| ︙ | ︙ | |||
864 865 866 867 868 869 870 |
** for consistency with how json_err() works.
*/
void json_warn( int code, char const * fmt, ... ){
cson_object * obj = NULL;
assert( (code>FSL_JSON_W_START)
&& (code<FSL_JSON_W_END)
&& "Invalid warning code.");
| | | | < | | | 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 |
** for consistency with how json_err() works.
*/
void json_warn( int code, char const * fmt, ... ){
cson_object * obj = NULL;
assert( (code>FSL_JSON_W_START)
&& (code<FSL_JSON_W_END)
&& "Invalid warning code.");
if(!g.json.warnings){
g.json.warnings = cson_new_array();
assert((NULL != g.json.warnings) && "Alloc error.");
json_gc_add("$WARNINGS",cson_array_value(g.json.warnings));
}
obj = cson_new_object();
cson_array_append(g.json.warnings, cson_object_value(obj));
cson_object_set(obj,"code",cson_value_new_integer(code));
if(fmt && *fmt){
/* FIXME: treat NULL fmt as standard warning message for
the code, but we don't have those yet.
*/
va_list vargs;
char * msg;
|
| ︙ | ︙ | |||
930 931 932 933 934 935 936 |
if( !*p || (separator == *p) ){
if( len ){/* append head..(head+len) as next array
element. */
cson_value * part = NULL;
char * zPart = NULL;
++rc;
assert( head != p );
| | < | 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 |
if( !*p || (separator == *p) ){
if( len ){/* append head..(head+len) as next array
element. */
cson_value * part = NULL;
char * zPart = NULL;
++rc;
assert( head != p );
zPart = (char*)fossil_malloc(len+1);
memcpy(zPart, head, len);
zPart[len] = 0;
if(doDeHttp){
dehttpize(zPart);
}
if( *zPart ){ /* should only fail if someone manages to url-encoded a NUL byte */
part = cson_value_new_string(zPart, strlen(zPart));
|
| ︙ | ︙ | |||
955 956 957 958 959 960 961 |
fossil_exit(1)
/* Not fossil_panic() b/c this code needs to be able to
run before some of the fossil/json bits are initialized,
and fossil_panic() calls into the JSON API.
*/
;
}
| | | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 |
fossil_exit(1)
/* Not fossil_panic() b/c this code needs to be able to
run before some of the fossil/json bits are initialized,
and fossil_panic() calls into the JSON API.
*/
;
}
fossil_free(zPart);
len = 0;
}
if( !*p ){
break;
}
head = p+1;
while( *head && fossil_isspace(*head) ){
|
| ︙ | ︙ | |||
988 989 990 991 992 993 994 |
**
** The returned value is owned by the caller. If not NULL then it
** _will_ have a JSON type of Array.
*/
cson_value * json_string_split2( char const * zStr,
char separator,
char doDeHttp ){
| < | | | | < < < | | 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 |
**
** The returned value is owned by the caller. If not NULL then it
** _will_ have a JSON type of Array.
*/
cson_value * json_string_split2( char const * zStr,
char separator,
char doDeHttp ){
cson_array * a = cson_new_array();
int rc = json_string_split( zStr, separator, doDeHttp, a );
if( 0>=rc ){
cson_free_array(a);
a = NULL;
}
return a ? cson_array_value(a) : NULL;
}
/*
** Performs some common initialization of JSON-related state. Must be
** called by the json_page_top() and json_cmd_top() dispatching
** functions to set up the JSON stat used by the dispatched functions.
|
| ︙ | ︙ | |||
1442 1443 1444 1445 1446 1447 1448 | INT(g.json, dispatchDepth); VAL(authToken, g.json.authToken); CSTR(g.json, jsonp); VAL(gc, g.json.gc.v); VAL(cmd, g.json.cmd.v); VAL(param, g.json.param.v); VAL(POST, g.json.post.v); | | | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 | INT(g.json, dispatchDepth); VAL(authToken, g.json.authToken); CSTR(g.json, jsonp); VAL(gc, g.json.gc.v); VAL(cmd, g.json.cmd.v); VAL(param, g.json.param.v); VAL(POST, g.json.post.v); VAL(warnings, cson_array_value(g.json.warnings)); /*cson_output_opt outOpt;*/ #undef INT #undef CSTR #undef VAL return cson_object_value(pay); |
| ︙ | ︙ | |||
1555 1556 1557 1558 1559 1560 1561 |
double span;
span = END_TIMER;
/* i'm actually seeing sub-ms runtimes in some tests, but a time of
0 is "just wrong", so we'll bump that up to 1ms.
*/
cson_object_set(o,"procTimeMs", cson_value_new_integer((cson_int_t)((span>1.0)?span:1)));
}
| | | | 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 |
double span;
span = END_TIMER;
/* i'm actually seeing sub-ms runtimes in some tests, but a time of
0 is "just wrong", so we'll bump that up to 1ms.
*/
cson_object_set(o,"procTimeMs", cson_value_new_integer((cson_int_t)((span>1.0)?span:1)));
}
if(g.json.warnings){
tmp = cson_array_value(g.json.warnings);
SET("warnings");
}
/* Only add the payload to SUCCESS responses. Else delete it. */
if( NULL != payload ){
if( resultCode ){
cson_value_free(payload);
|
| ︙ | ︙ | |||
1663 1664 1665 1666 1667 1668 1669 1670 |
assert( (code>=1000) && (code<=9999) );
free(g.zErrMsg);
g.json.resultCode = code;
if(!fmt || !*fmt){
g.zErrMsg = mprintf("%s", json_err_cstr(code));
}else{
va_list vargs;
va_start(vargs,fmt);
| > | | 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 |
assert( (code>=1000) && (code<=9999) );
free(g.zErrMsg);
g.json.resultCode = code;
if(!fmt || !*fmt){
g.zErrMsg = mprintf("%s", json_err_cstr(code));
}else{
va_list vargs;
char * msg;
va_start(vargs,fmt);
msg = vmprintf(fmt, vargs);
va_end(vargs);
g.zErrMsg = msg;
}
return code;
}
/*
|
| ︙ | ︙ | |||
1695 1696 1697 1698 1699 1700 1701 |
if(!a){
a = cson_new_array();
assert(NULL!=a);
}
if(!colNames){
colNamesV = cson_sqlite3_column_names(pStmt->pStmt);
assert(NULL != colNamesV);
| | < > | 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 |
if(!a){
a = cson_new_array();
assert(NULL!=a);
}
if(!colNames){
colNamesV = cson_sqlite3_column_names(pStmt->pStmt);
assert(NULL != colNamesV);
/*Why? cson_value_add_reference(colNamesV) avoids an ownership problem*/;
colNames = cson_value_get_array(colNamesV);
assert(NULL != colNames);
}
row = cson_sqlite3_row_to_object2(pStmt->pStmt, colNames);
if(!row && !warnMsg){
warnMsg = "Could not convert at least one result row to JSON.";
continue;
}
if( 0 != cson_array_append(a, row) ){
cson_value_free(row);
if(pTgt != a) {
cson_free_array(a);
}
assert( 0 && "Alloc error.");
return NULL;
}
}
cson_value_free(colNamesV);
if(warnMsg){
json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, warnMsg );
}
|
| ︙ | ︙ | |||
1827 1828 1829 1830 1831 1832 1833 |
}
/*
** Impl of /json/resultCodes
**
*/
cson_value * json_page_resultCodes(){
| < | < | | | 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 |
}
/*
** Impl of /json/resultCodes
**
*/
cson_value * json_page_resultCodes(){
cson_array * list = cson_new_array();
cson_object * obj = NULL;
cson_string * kRC;
cson_string * kSymbol;
cson_string * kNumber;
cson_string * kDesc;
cson_array_reserve( list, 35 );
kRC = cson_new_string("resultCode",10);
kSymbol = cson_new_string("cSymbol",7);
kNumber = cson_new_string("number",6);
kDesc = cson_new_string("description",11);
#define C(K) obj = cson_new_object(); \
cson_object_set_s(obj, kRC, json_new_string(json_rc_cstr(FSL_JSON_E_##K)) ); \
cson_object_set_s(obj, kSymbol, json_new_string("FSL_JSON_E_"#K) ); \
cson_object_set_s(obj, kNumber, cson_value_new_integer(FSL_JSON_E_##K) ); \
cson_object_set_s(obj, kDesc, json_new_string(json_err_cstr(FSL_JSON_E_##K))); \
cson_array_append( list, cson_object_value(obj) ); obj = NULL;
C(GENERIC);
C(INVALID_REQUEST);
C(UNKNOWN_COMMAND);
C(UNKNOWN);
C(TIMEOUT);
C(ASSERT);
|
| ︙ | ︙ | |||
1886 1887 1888 1889 1890 1891 1892 |
C(STMT_BIND);
C(STMT_EXEC);
C(DB_LOCKED);
C(DB_NEEDS_REBUILD);
C(DB_NOT_FOUND);
C(DB_NOT_VALID);
#undef C
| | | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 |
C(STMT_BIND);
C(STMT_EXEC);
C(DB_LOCKED);
C(DB_NEEDS_REBUILD);
C(DB_NOT_FOUND);
C(DB_NOT_VALID);
#undef C
return cson_array_value(list);
}
/*
** /json/version implementation.
**
** Returns the payload object (owned by the caller).
|
| ︙ | ︙ | |||
1910 1911 1912 1913 1914 1915 1916 |
FSET(MANIFEST_DATE,"manifestDate");
FSET(MANIFEST_YEAR,"manifestYear");
FSET(RELEASE_VERSION,"releaseVersion");
cson_object_set( jobj, "releaseVersionNumber",
cson_value_new_integer(RELEASE_VERSION_NUMBER) );
cson_object_set( jobj, "resultCodeParanoiaLevel",
cson_value_new_integer(g.json.errorDetailParanoia) );
| | | 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 |
FSET(MANIFEST_DATE,"manifestDate");
FSET(MANIFEST_YEAR,"manifestYear");
FSET(RELEASE_VERSION,"releaseVersion");
cson_object_set( jobj, "releaseVersionNumber",
cson_value_new_integer(RELEASE_VERSION_NUMBER) );
cson_object_set( jobj, "resultCodeParanoiaLevel",
cson_value_new_integer(g.json.errorDetailParanoia) );
FSET(FOSSIL_JSON_API_VERSION, "jsonApiVersion" );
#undef FSET
return jval;
}
/*
** Returns the current user's capabilities string as a String value.
|
| ︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 | ADD(Setup,"setup"); ADD(Admin,"admin"); ADD(Delete,"delete"); ADD(Password,"password"); ADD(Query,"query"); /* don't think this one is actually used */ ADD(Write,"checkin"); ADD(Read,"checkout"); | | | 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 | ADD(Setup,"setup"); ADD(Admin,"admin"); ADD(Delete,"delete"); ADD(Password,"password"); ADD(Query,"query"); /* don't think this one is actually used */ ADD(Write,"checkin"); ADD(Read,"checkout"); ADD(Hyperlink,"history"); ADD(Clone,"clone"); ADD(RdWiki,"readWiki"); ADD(NewWiki,"createWiki"); ADD(ApndWiki,"appendWiki"); ADD(WrWiki,"editWiki"); ADD(RdTkt,"readTicket"); ADD(NewTkt,"createTicket"); |
| ︙ | ︙ | |||
2314 2315 2316 2317 2318 2319 2320 | } payload = json_create_response(rc, NULL, payload); json_send_response(payload); cson_value_free(payload); return rc; } | | > | 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 | } payload = json_create_response(rc, NULL, payload); json_send_response(payload); cson_value_free(payload); return rc; } #ifdef FOSSIL_ENABLE_JSON /* dupe ifdef needed for mkindex */ /* ** WEBPAGE: json ** ** Pages under /json/... must be entered into JsonPageDefs. ** This function dispatches them, and is the HTTP equivalent of ** json_cmd_top(). */ |
| ︙ | ︙ | |||
2337 2338 2339 2340 2341 2342 2343 |
" Try one of: ");
return;
}
json_dispatch_root_command( zCommand );
}
#endif /* FOSSIL_ENABLE_JSON for mkindex */
| | > > > | < < | 2337 2338 2339 2340 2341 2342 2343 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 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 |
" Try one of: ");
return;
}
json_dispatch_root_command( zCommand );
}
#endif /* FOSSIL_ENABLE_JSON for mkindex */
#ifdef FOSSIL_ENABLE_JSON
/* dupe ifdef needed for mkindex */
/*
** This function dispatches json commands and is the CLI equivalent of
** json_page_top().
**
** COMMAND: json
**
** Usage: %fossil json SUBCOMMAND ?OPTIONS?
**
** In CLI mode, the -R REPO common option is supported. Due to limitations
** in the argument dispatching code, any -FLAGS must come after the final
** sub- (or subsub-) command.
**
** The commands include:
**
** anonymousPassord
** artifact
** branch
** cap
** config
** diff
** dir
** g
** login
** logout
** query
** rebuild
** report
** resultCodes
** stat
** tag
** timeline
** user
** version (alias: HAI)
** whoami
** wiki
**
** Run '%fossil json' without any subcommand to see the full list (but be
** aware that some listed might not yet be fully implemented).
**
*/
void json_cmd_top(void){
char const * cmd = NULL;
int rc = 0;
BEGIN_TIMER;
memset( &g.perm, 0xff, sizeof(g.perm) )
|
| ︙ | ︙ |
Changes to src/json_artifact.c.
| ︙ | ︙ | |||
27 28 29 30 31 32 33 34 | ** Internal callback for /json/artifact handlers. rid refers to ** the rid of a given type of artifact, and each callback is ** specialized to return a JSON form of one type of artifact. ** ** Implementations may assert() that rid refers to requested artifact ** type, since mismatches in the artifact types come from ** json_page_artifact() as opposed to client data. */ | > > > > | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
** Internal callback for /json/artifact handlers. rid refers to
** the rid of a given type of artifact, and each callback is
** specialized to return a JSON form of one type of artifact.
**
** Implementations may assert() that rid refers to requested artifact
** type, since mismatches in the artifact types come from
** json_page_artifact() as opposed to client data.
**
** The pParent parameter points to the response payload object. It
** _may_ be used to populate "top-level" information in the response
** payload, but normally this is neither necessary nor desired.
*/
typedef cson_value * (*artifact_f)( cson_object * pParent, int rid );
/*
** Internal per-artifact-type dispatching helper.
*/
typedef struct ArtifactDispatchEntry {
/**
Artifact type name, e.g. "checkin", "ticket", "wiki".
|
| ︙ | ︙ | |||
158 159 160 161 162 163 164 |
tmpV = json_tags_for_checkin_rid(rid,0);
if(tmpV){
SET("tags",tmpV);
}
if( showFiles ){
| | | | 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 |
tmpV = json_tags_for_checkin_rid(rid,0);
if(tmpV){
SET("tags",tmpV);
}
if( showFiles ){
tmpV = json_get_changed_files(rid, 1);
if(tmpV){
SET("files",tmpV);
}
}
#undef SET
}
db_finalize(&q);
return v;
}
/*
** Very incomplete/incorrect impl of /json/artifact/TICKET_ID.
*/
cson_value * json_artifact_ticket( cson_object * zParent, int rid ){
cson_object * pay = NULL;
Manifest *pTktChng = NULL;
static cson_value * eventTypeLabel = NULL;
if(! g.perm.RdTkt ){
g.json.resultCode = FSL_JSON_E_DENIED;
return NULL;
}
|
| ︙ | ︙ | |||
203 204 205 206 207 208 209 | manifest_destroy(pTktChng); return cson_object_value(pay); } /* ** Sub-impl of /json/artifact for checkins. */ | | | > > > > > > | > > > > | | > > > | | > | > > > | < | | < | 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 |
manifest_destroy(pTktChng);
return cson_object_value(pay);
}
/*
** Sub-impl of /json/artifact for checkins.
*/
static cson_value * json_artifact_ci( cson_object * zParent, int rid ){
if(!g.perm.Read){
json_set_err( FSL_JSON_E_DENIED, "Viewing checkins requires 'o' privileges." );
return NULL;
}else{
cson_value * artV = json_artifact_for_ci(rid, 1);
cson_object * art = cson_value_get_object(artV);
if(art){
cson_object_merge( zParent, art, CSON_MERGE_REPLACE );
cson_free_object(art);
}
return cson_object_value(zParent);
}
}
/*
** Internal mapping of /json/artifact/FOO commands/callbacks.
*/
static ArtifactDispatchEntry ArtifactDispatchList[] = {
{"checkin", json_artifact_ci},
{"file", json_artifact_file},
{"tag", NULL},
{"ticket", json_artifact_ticket},
{"wiki", json_artifact_wiki},
/* Final entry MUST have a NULL name. */
{NULL,NULL}
};
/*
** Internal helper which returns:
**
** If the "format" (CLI: -f) flag is set function returns the same as
** json_wiki_get_content_format_flag(), else it returns true (non-0)
** if either the includeContent (HTTP) or -content|-c boolean flags
** (CLI) are set.
*/
static char json_artifact_get_content_format_flag(){
enum { MagicValue = -9 };
char contentFormat = json_wiki_get_content_format_flag(MagicValue);
if(MagicValue == contentFormat){
contentFormat = json_find_option_bool("includeContent","content","c",0) /* deprecated */ ? -1 : 0;
}
return contentFormat;
}
extern char json_wiki_get_content_format_flag( char defaultValue ) /* json_wiki.c */;
cson_value * json_artifact_wiki(cson_object * zParent, int rid){
if( ! g.perm.RdWiki ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'j' privileges.");
return NULL;
}else{
enum { MagicValue = -9 };
char const contentFormat = json_artifact_get_content_format_flag();
return json_get_wiki_page_by_rid(rid, contentFormat);
}
}
/*
** Internal helper for routines which add a "status" flag to file
** artifact data. isNew and isDel should be the "is this object new?"
|
| ︙ | ︙ | |||
264 265 266 267 268 269 270 |
return isNew
? "added"
: (isDel
? "removed"
: "modified");
}
| | | > > | | > > | < | > > > > > > > > > > | > > > > > | > > > | > > > > > > > > > > > | > > | > | | 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 |
return isNew
? "added"
: (isDel
? "removed"
: "modified");
}
cson_value * json_artifact_file(cson_object * zParent, int rid){
cson_object * pay = NULL;
Stmt q = empty_Stmt;
cson_array * checkin_arr = NULL;
char contentFormat;
i64 contentSize = -1;
char * parentUuid;
if( ! g.perm.Read ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'o' privileges.");
return NULL;
}
pay = zParent;
contentFormat = json_artifact_get_content_format_flag();
if( 0 != contentFormat ){
Blob content = empty_blob;
const char *zMime;
char const * zFormat = (contentFormat<1) ? "raw" : "html";
content_get(rid, &content);
zMime = mimetype_from_content(&content);
cson_object_set(zParent, "contentType",
json_new_string(zMime ? zMime : "text/plain"));
if(!zMime){/* text/plain */
if(0 < blob_size(&content)){
if( 0 < contentFormat ){/*HTML-size it*/
Blob html = empty_blob;
wiki_convert(&content, &html, 0);
assert( blob_size(&content) < blob_size(&html) );
blob_swap( &html, &content );
assert( blob_size(&content) > blob_size(&html) );
blob_reset( &html );
}/*else as-is*/
}
cson_object_set(zParent, "content",
cson_value_new_string(blob_str(&content),
(unsigned int)blob_size(&content)));
}/*else binary: ignore*/
contentSize = blob_size(&content);
cson_object_set(zParent, "contentSize", json_new_int(contentSize) );
cson_object_set(zParent, "contentFormat", json_new_string(zFormat) );
blob_reset(&content);
}
contentSize = db_int64(-1, "SELECT size FROM blob WHERE rid=%d", rid);
assert( -1 < contentSize );
cson_object_set(zParent, "size", json_new_int(contentSize) );
parentUuid = db_text(NULL,
"SELECT DISTINCT p.uuid "
"FROM blob p, blob f, mlink m "
"WHERE m.pid=p.rid "
"AND m.fid=f.rid "
"AND f.rid=%d",
rid
);
if(parentUuid){
cson_object_set( zParent, "parent", json_new_string(parentUuid) );
fossil_free(parentUuid);
}
/* Find checkins associated with this file... */
db_prepare(&q,
"SELECT filename.name AS name, "
" (mlink.pid==0) AS isNew,"
" (mlink.fid==0) AS isDel,"
" cast(strftime('%%s',event.mtime) as int) AS timestamp,"
" coalesce(event.ecomment,event.comment) as comment,"
" coalesce(event.euser,event.user) as user,"
#if 0
" a.size AS size," /* same for all checkins. */
#endif
" b.uuid as checkin, "
#if 0
" mlink.mperm as mperm,"
#endif
" coalesce((SELECT value FROM tagxref"
" WHERE tagid=%d AND tagtype>0 AND "
" rid=mlink.mid),'trunk') as branch"
" FROM mlink, filename, event, blob a, blob b"
|
| ︙ | ︙ | |||
324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
/* TODO: add a "state" flag for the file in each checkin,
e.g. "modified", "new", "deleted".
*/
checkin_arr = cson_new_array();
cson_object_set(pay, "checkins", cson_array_value(checkin_arr));
while( (SQLITE_ROW==db_step(&q) ) ){
cson_object * row = cson_value_get_object(cson_sqlite3_row_to_object(q.pStmt));
char const isNew = cson_value_get_bool(cson_object_get(row,"isNew"));
char const isDel = cson_value_get_bool(cson_object_get(row,"isDel"));
cson_object_set(row, "isNew", NULL);
cson_object_set(row, "isDel", NULL);
cson_object_set(row, "state",
json_new_string(json_artifact_status_to_string(isNew, isDel)));
cson_array_append( checkin_arr, cson_object_value(row) );
| > | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
/* TODO: add a "state" flag for the file in each checkin,
e.g. "modified", "new", "deleted".
*/
checkin_arr = cson_new_array();
cson_object_set(pay, "checkins", cson_array_value(checkin_arr));
while( (SQLITE_ROW==db_step(&q) ) ){
cson_object * row = cson_value_get_object(cson_sqlite3_row_to_object(q.pStmt));
/* FIXME: move this isNew/isDel stuff into an SQL CASE statement. */
char const isNew = cson_value_get_bool(cson_object_get(row,"isNew"));
char const isDel = cson_value_get_bool(cson_object_get(row,"isDel"));
cson_object_set(row, "isNew", NULL);
cson_object_set(row, "isDel", NULL);
cson_object_set(row, "state",
json_new_string(json_artifact_status_to_string(isNew, isDel)));
cson_array_append( checkin_arr, cson_object_value(row) );
|
| ︙ | ︙ | |||
369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
if( db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'event-%q*'", zName) ){
zType = "tag";
goto handle_entry;
}
}
blob_set(&uuid,zName);
rc = name_to_uuid(&uuid,-1,"*");
if(1==rc){
g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
goto error;
}else if(2==rc){
g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
goto error;
}
| > | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
if( db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'event-%q*'", zName) ){
zType = "tag";
goto handle_entry;
}
}
blob_set(&uuid,zName);
rc = name_to_uuid(&uuid,-1,"*");
/* FIXME: check for a filename if all else fails. */
if(1==rc){
g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
goto error;
}else if(2==rc){
g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
goto error;
}
|
| ︙ | ︙ | |||
409 410 411 412 413 414 415 416 417 418 419 420 |
}
error:
assert( 0 != g.json.resultCode );
goto veryend;
handle_entry:
assert( (NULL != zType) && "Internal dispatching error." );
for( ; dispatcher->name; ++dispatcher ){
if(0!=strcmp(dispatcher->name, zType)){
continue;
}else{
| > | < | | < > > > > > | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
}
error:
assert( 0 != g.json.resultCode );
goto veryend;
handle_entry:
pay = cson_new_object();
assert( (NULL != zType) && "Internal dispatching error." );
for( ; dispatcher->name; ++dispatcher ){
if(0!=strcmp(dispatcher->name, zType)){
continue;
}else{
entry = (*dispatcher->func)(pay, rid);
break;
}
}
if(!g.json.resultCode){
assert( NULL != entry );
assert( NULL != zType );
cson_object_set( pay, "type", json_new_string(zType) );
cson_object_set( pay, "uuid", json_new_string(zUuid) );
/*cson_object_set( pay, "name", json_new_string(zName ? zName : zUuid) );*/
/*cson_object_set( pay, "rid", cson_value_new_integer(rid) );*/
if(cson_value_is_object(entry) && (cson_value_get_object(entry) != pay)){
cson_object_set(pay, "artifact", entry);
}
}
veryend:
blob_reset(&uuid);
if(g.json.resultCode && pay){
cson_free_object(pay);
pay = NULL;
}
return cson_object_value(pay);
}
#endif /* FOSSIL_ENABLE_JSON */
|
Changes to src/json_detail.h.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 | ** */ #include "cson_amalgamation.h" /** FOSSIL_JSON_API_VERSION holds the date (YYYYMMDD) of the latest | | | | > > > > > | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | ** */ #include "cson_amalgamation.h" /** FOSSIL_JSON_API_VERSION holds the date (YYYYMMDD) of the latest "significant" change to the JSON API (a change in an interface or new functionality). It is sent as part of the /json/version request. We could arguably add it to each response or even add a version number to each response type, allowing very fine (too fine?) granularity in compatibility change notification. The version number could be included in part of the command dispatching framework, allowing the top-level dispatching code to deal with it (for the most part). */ #define FOSSIL_JSON_API_VERSION "20120713" /* ** Impl details for the JSON API which need to be shared ** across multiple C files. */ /* |
| ︙ | ︙ | |||
170 171 172 173 174 175 176 177 178 179 180 181 182 183 | ** Which mode(s) of execution does func() support: ** ** <0 = CLI only, >0 = HTTP only, 0==both ** ** Now that we can simulate POST in CLI mode, the distinction ** between them has disappeared in most (or all) cases, so 0 is the ** the standard value. */ char runMode; } JsonPageDef; /* ** Holds common keys used for various JSON API properties. */ | > > > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | ** Which mode(s) of execution does func() support: ** ** <0 = CLI only, >0 = HTTP only, 0==both ** ** Now that we can simulate POST in CLI mode, the distinction ** between them has disappeared in most (or all) cases, so 0 is the ** the standard value. ** ** 201207: this is not needed any more. We can get rid of it. Or ** keep it around in case it becomes useful again at some point. */ char runMode; } JsonPageDef; /* ** Holds common keys used for various JSON API properties. */ |
| ︙ | ︙ | |||
210 211 212 213 214 215 216 | ** values and NULL is returned. If non-NULL is returned, ownership is ** transfered to the caller (but the g.json error state might still be ** set in that case, so the caller must check that or pass it on up ** the dispatch chain). */ cson_value * json_page_dispatch_helper(JsonPageDef const * pages); | < < < < < < < < < < < < < < < < | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | ** values and NULL is returned. If non-NULL is returned, ownership is ** transfered to the caller (but the g.json error state might still be ** set in that case, so the caller must check that or pass it on up ** the dispatch chain). */ cson_value * json_page_dispatch_helper(JsonPageDef const * pages); /* ** Convenience wrapper around cson_value_new_string(). ** Returns NULL if str is NULL or on allocation error. */ cson_value * json_new_string( char const * str ); /* |
| ︙ | ︙ | |||
262 263 264 265 266 267 268 269 270 271 | ** ** Whether or not we need to take args from CLI or POST data makes a ** difference in argument/parameter handling in many JSON rountines, ** and thus this distinction. */ char fossil_has_json(); #endif/*FOSSIL_JSON_DETAIL_H_INCLUDED*/ #endif /* FOSSIL_ENABLE_JSON */ | > > > | 254 255 256 257 258 259 260 261 262 263 264 265 266 |
**
** Whether or not we need to take args from CLI or POST data makes a
** difference in argument/parameter handling in many JSON rountines,
** and thus this distinction.
*/
char fossil_has_json();
enum json_get_changed_files_flags {
json_get_changed_files_ELIDE_PARENT = 1 << 0
};
#endif/*FOSSIL_JSON_DETAIL_H_INCLUDED*/
#endif /* FOSSIL_ENABLE_JSON */
|
Changes to src/json_dir.c.
| ︙ | ︙ | |||
64 65 66 67 68 69 70 | char const * zDX = NULL; int nD; char * zUuid = NULL; char const * zCI = NULL; Manifest * pM = NULL; Stmt q = empty_Stmt; int rid = 0; | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
char const * zDX = NULL;
int nD;
char * zUuid = NULL;
char const * zCI = NULL;
Manifest * pM = NULL;
Stmt q = empty_Stmt;
int rid = 0;
if( !g.perm.Read ){
json_set_err(FSL_JSON_E_DENIED, "Requires 'o' permissions.");
return NULL;
}
zCI = json_find_option_cstr("checkin",NULL,"ci" );
/* If a specific check-in is requested, fetch and parse it. If the
** specific check-in does not exist, clear zCI. zCI==0 will cause all
** files from all check-ins to be displayed.
|
| ︙ | ︙ |
Changes to src/json_query.c.
| ︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
"'sql' (-s) argument is missing.");
return NULL;
}
zFmt = json_find_option_cstr2("format",NULL,"f",3);
if(!zFmt) zFmt = "o";
db_prepare(&q,"%s", zSql);
switch(*zFmt){
case 'a':
check = cson_sqlite3_stmt_to_json(q.pStmt, &payV, 0);
break;
case 'o':
default:
check = cson_sqlite3_stmt_to_json(q.pStmt, &payV, 1);
| > > > > > > > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
"'sql' (-s) argument is missing.");
return NULL;
}
zFmt = json_find_option_cstr2("format",NULL,"f",3);
if(!zFmt) zFmt = "o";
db_prepare(&q,"%s", zSql);
if( 0 == sqlite3_column_count( q.pStmt ) ){
json_set_err(FSL_JSON_E_USAGE,
"Input query has no result columns. "
"Only SELECT-like queries are supported.");
db_finalize(&q);
return NULL;
}
switch(*zFmt){
case 'a':
check = cson_sqlite3_stmt_to_json(q.pStmt, &payV, 0);
break;
case 'o':
default:
check = cson_sqlite3_stmt_to_json(q.pStmt, &payV, 1);
|
| ︙ | ︙ |
Changes to src/json_report.c.
| ︙ | ︙ | |||
49 50 51 52 53 54 55 |
*/
cson_value * json_page_report(){
if(!g.perm.RdTkt && !g.perm.NewTkt ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'r' or 'n' permissions.");
return NULL;
}
| | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
*/
cson_value * json_page_report(){
if(!g.perm.RdTkt && !g.perm.NewTkt ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'r' or 'n' permissions.");
return NULL;
}
return json_page_dispatch_helper(JsonPageDefs_Report);
}
/*
** Searches the environment for a "report" parameter
** (CLI: -report/-r #).
**
** If one is not found and argPos is >0 then json_command_arg()
|
| ︙ | ︙ | |||
76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
nReport = atoi(arg);
}
}
return nReport;
}
static cson_value * json_report_create(){
return NULL;
}
static cson_value * json_report_get(){
int nReport;
Stmt q = empty_Stmt;
cson_value * pay = NULL;
| > | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
nReport = atoi(arg);
}
}
return nReport;
}
static cson_value * json_report_create(){
json_set_err(FSL_JSON_E_NYI, NULL);
return NULL;
}
static cson_value * json_report_get(){
int nReport;
Stmt q = empty_Stmt;
cson_value * pay = NULL;
|
| ︙ | ︙ | |||
246 247 248 249 250 251 252 | goto end; error: assert(0 != g.json.resultCode); cson_value_free( cson_object_value(pay) ); pay = NULL; | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
goto end;
error:
assert(0 != g.json.resultCode);
cson_value_free( cson_object_value(pay) );
pay = NULL;
end:
return pay ? cson_object_value(pay) : NULL;
}
static cson_value * json_report_save(){
return NULL;
}
#endif /* FOSSIL_ENABLE_JSON */
|
Changes to src/json_tag.c.
| ︙ | ︙ | |||
111 112 113 114 115 116 117 118 |
cson_object_set(pay, "value", (zValue&&*zValue)
? json_new_string(zValue)
: cson_value_null());
cson_object_set(pay, "propagate", cson_value_new_bool(fPropagate));
cson_object_set(pay, "raw", cson_value_new_bool(fRaw));
{
Blob uu = empty_blob;
blob_append(&uu, zName, -1);
| > | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
cson_object_set(pay, "value", (zValue&&*zValue)
? json_new_string(zValue)
: cson_value_null());
cson_object_set(pay, "propagate", cson_value_new_bool(fPropagate));
cson_object_set(pay, "raw", cson_value_new_bool(fRaw));
{
Blob uu = empty_blob;
int rc;
blob_append(&uu, zName, -1);
rc = name_to_uuid(&uu, 9, "*");
if(0!=rc){
json_set_err(FSL_JSON_E_UNKNOWN,"Could not convert name back to UUID!");
blob_reset(&uu);
goto error;
}
cson_object_set(pay, "appliedTo", json_new_string(blob_buffer(&uu)));
blob_reset(&uu);
|
| ︙ | ︙ |
Changes to src/json_timeline.c.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 |
*/
cson_value * json_page_timeline(){
#if 0
/* The original timeline code does not require 'h' access,
but it arguably should. For JSON mode i think one could argue
that History permissions are required.
*/
| | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
*/
cson_value * json_page_timeline(){
#if 0
/* The original timeline code does not require 'h' access,
but it arguably should. For JSON mode i think one could argue
that History permissions are required.
*/
if(! g.perm.Hyperlink && !g.perm.Read ){
json_set_err(FSL_JSON_E_DENIED, "Timeline requires 'h' or 'o' access.");
return NULL;
}
#endif
return json_page_dispatch_helper(&JsonPageDefs_Timeline[0]);
}
|
| ︙ | ︙ | |||
278 279 280 281 282 283 284 285 286 287 288 289 290 |
blob_appendf(pSql,"LIMIT %d ",limit);
}
if(pPayload){
cson_object_set(pPayload, "limit", json_new_int(limit));
}
return 0;
}
/*
** If any files are associated with the given rid, a JSON array
** containing information about them is returned (and is owned by the
** caller). If no files are associated with it then NULL is returned.
*/
| > > > > | | 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 |
blob_appendf(pSql,"LIMIT %d ",limit);
}
if(pPayload){
cson_object_set(pPayload, "limit", json_new_int(limit));
}
return 0;
}
/*
** If any files are associated with the given rid, a JSON array
** containing information about them is returned (and is owned by the
** caller). If no files are associated with it then NULL is returned.
**
** flags may optionally be a bitmask of json_get_changed_files flags,
** or 0 for defaults.
*/
cson_value * json_get_changed_files(int rid, int flags){
cson_value * rowsV = NULL;
cson_array * rows = NULL;
Stmt q = empty_Stmt;
db_prepare(&q,
"SELECT (pid==0) AS isnew,"
" (fid==0) AS isdel,"
" (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
|
| ︙ | ︙ | |||
314 315 316 317 318 319 320 |
if(!rowsV){
rowsV = cson_value_new_array();
rows = cson_value_get_array(rowsV);
}
cson_array_append( rows, rowV );
cson_object_set(row, "name", json_new_string(db_column_text(&q,2)));
cson_object_set(row, "uuid", json_new_string(db_column_text(&q,3)));
| | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
if(!rowsV){
rowsV = cson_value_new_array();
rows = cson_value_get_array(rowsV);
}
cson_array_append( rows, rowV );
cson_object_set(row, "name", json_new_string(db_column_text(&q,2)));
cson_object_set(row, "uuid", json_new_string(db_column_text(&q,3)));
if(!isNew && (flags & json_get_changed_files_ELIDE_PARENT)){
cson_object_set(row, "parent", json_new_string(db_column_text(&q,4)));
}
cson_object_set(row, "size", json_new_int(db_column_int(&q,5)));
cson_object_set(row, "state",
json_new_string(json_artifact_status_to_string(isNew,isDel)));
zDownload = mprintf("/raw/%s?name=%s",
|
| ︙ | ︙ | |||
424 425 426 427 428 429 430 | cson_value * listV = NULL; cson_array * list = NULL; int check = 0; char showFiles = -1/*magic number*/; Stmt q = empty_Stmt; char warnRowToJsonFailed = 0; Blob sql = empty_blob; | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
cson_value * listV = NULL;
cson_array * list = NULL;
int check = 0;
char showFiles = -1/*magic number*/;
Stmt q = empty_Stmt;
char warnRowToJsonFailed = 0;
Blob sql = empty_blob;
if( !g.perm.Hyperlink ){
/* Reminder to self: HTML impl requires 'o' (Read)
rights.
*/
json_set_err( FSL_JSON_E_DENIED, "Checkin timeline requires 'h' access." );
return NULL;
}
showFiles = json_find_option_bool("files",NULL,"f",0);
|
| ︙ | ︙ |
Changes to src/json_user.c.
| ︙ | ︙ | |||
354 355 356 357 358 359 360 | puts(blob_str(&sql)); cson_output_FILE( cson_object_value(pUser), stdout, NULL ); #endif db_prepare(&q, "%s", blob_str(&sql)); db_exec(&q); db_finalize(&q); #if TRY_LOGIN_GROUP | | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
puts(blob_str(&sql));
cson_output_FILE( cson_object_value(pUser), stdout, NULL );
#endif
db_prepare(&q, "%s", blob_str(&sql));
db_exec(&q);
db_finalize(&q);
#if TRY_LOGIN_GROUP
if( zPW || cson_value_get_bool(forceLogout) ){
Blob groupSql = empty_blob;
char * zErr = NULL;
blob_appendf(&groupSql,
"INSERT INTO user(login)"
" SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
zName, zName
);
|
| ︙ | ︙ | |||
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
a JSON form of it... */
cson_object * u = cson_new_object();
char const * str = NULL;
char b = -1;
int i = -1;
int uid = -1;
cson_value * payload = NULL;
#define PROP(LK,SK) str = json_find_option_cstr(LK,NULL,SK); \
if(str){ cson_object_set(u, LK, json_new_string(str)); } (void)0
PROP("name","n");
PROP("password","p");
PROP("info","i");
PROP("capabilities","c");
#undef PROP
#define PROP(LK,DFLT) b = json_find_option_bool(LK,NULL,NULL,DFLT); \
if(DFLT!=b){ cson_object_set(u, LK, cson_value_new_bool(b)); } (void)0
PROP("forceLogout",-1);
#undef PROP
#define PROP(LK,DFLT) i = json_find_option_int(LK,NULL,NULL,DFLT); \
if(DFLT != i){ cson_object_set(u, LK, cson_value_new_integer(i)); } (void)0
| > > | 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
a JSON form of it... */
cson_object * u = cson_new_object();
char const * str = NULL;
char b = -1;
int i = -1;
int uid = -1;
cson_value * payload = NULL;
/* String properties... */
#define PROP(LK,SK) str = json_find_option_cstr(LK,NULL,SK); \
if(str){ cson_object_set(u, LK, json_new_string(str)); } (void)0
PROP("name","n");
PROP("password","p");
PROP("info","i");
PROP("capabilities","c");
#undef PROP
/* Boolean properties... */
#define PROP(LK,DFLT) b = json_find_option_bool(LK,NULL,NULL,DFLT); \
if(DFLT!=b){ cson_object_set(u, LK, cson_value_new_bool(b)); } (void)0
PROP("forceLogout",-1);
#undef PROP
#define PROP(LK,DFLT) i = json_find_option_int(LK,NULL,NULL,DFLT); \
if(DFLT != i){ cson_object_set(u, LK, cson_value_new_integer(i)); } (void)0
|
| ︙ | ︙ |
Changes to src/json_wiki.c.
1 2 | #ifdef FOSSIL_ENABLE_JSON /* | | | 1 2 3 4 5 6 7 8 9 10 | #ifdef FOSSIL_ENABLE_JSON /* ** Copyright (c) 2011-12 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 |
| ︙ | ︙ | |||
46 47 48 49 50 51 52 |
/*
** Implements the /json/wiki family of pages/commands.
**
*/
cson_value * json_page_wiki(){
| | > > > > > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
/*
** Implements the /json/wiki family of pages/commands.
**
*/
cson_value * json_page_wiki(){
return json_page_dispatch_helper(JsonPageDefs_Wiki);
}
/*
** Returns the UUID for the given wiki blob RID, or NULL if not
** found. The returned string is allocated via db_text() and must be
** free()d by the caller.
*/
char * json_wiki_get_uuid_for_rid( int rid )
{
return db_text(NULL,
"SELECT b.uuid FROM tag t, tagxref x, blob b"
" WHERE x.tagid=t.tagid AND t.tagname GLOB 'wiki-*' "
" AND b.rid=x.rid AND b.rid=%d"
" ORDER BY x.mtime DESC LIMIT 1",
|
| ︙ | ︙ | |||
81 82 83 84 85 86 87 |
Manifest * pWiki = NULL;
if( NULL == (pWiki = manifest_get(rid, CFTYPE_WIKI)) ){
json_set_err( FSL_JSON_E_UNKNOWN,
"Error reading wiki page from manifest (rid=%d).",
rid );
return NULL;
}else{
| < | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
Manifest * pWiki = NULL;
if( NULL == (pWiki = manifest_get(rid, CFTYPE_WIKI)) ){
json_set_err( FSL_JSON_E_UNKNOWN,
"Error reading wiki page from manifest (rid=%d).",
rid );
return NULL;
}else{
unsigned int len = 0;
cson_object * pay = cson_new_object();
char const * zBody = pWiki->zWiki;
char const * zFormat = NULL;
char * zUuid = json_wiki_get_uuid_for_rid(rid);
cson_object_set(pay,"name",json_new_string(pWiki->zWikiTitle));
cson_object_set(pay,"uuid",json_new_string(zUuid));
|
| ︙ | ︙ | |||
105 106 107 108 109 110 111 |
cson_object_set(pay,FossilJsonKeys.timestamp,
json_julian_to_timestamp(pWiki->rDate));
if(0 == contentFormat){
cson_object_set(pay,"size",
json_new_int((cson_int_t)(zBody?strlen(zBody):0)));
}else{
if( contentFormat>0 ){/*HTML-ize it*/
| < > | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
cson_object_set(pay,FossilJsonKeys.timestamp,
json_julian_to_timestamp(pWiki->rDate));
if(0 == contentFormat){
cson_object_set(pay,"size",
json_new_int((cson_int_t)(zBody?strlen(zBody):0)));
}else{
if( contentFormat>0 ){/*HTML-ize it*/
Blob content = empty_blob;
Blob raw = empty_blob;
zFormat = "html";
if(zBody && *zBody){
blob_append(&raw,zBody,-1);
wiki_convert(&raw,&content,0);
len = (unsigned int)blob_size(&content);
}
cson_object_set(pay,"size",json_new_int((cson_int_t)len));
cson_object_set(pay,"content",
|
| ︙ | ︙ | |||
490 491 492 493 494 495 496 | int argPos = g.json.dispatchDepth; int r1 = 0, r2 = 0; Manifest * pW1 = NULL, *pW2 = NULL; Blob w1 = empty_blob, w2 = empty_blob, d = empty_blob; char const * zErrTag = NULL; int diffFlags; char * zUuid = NULL; | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
int argPos = g.json.dispatchDepth;
int r1 = 0, r2 = 0;
Manifest * pW1 = NULL, *pW2 = NULL;
Blob w1 = empty_blob, w2 = empty_blob, d = empty_blob;
char const * zErrTag = NULL;
int diffFlags;
char * zUuid = NULL;
if( !g.perm.Hyperlink ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'h' permissions.");
return NULL;
}
zV1 = json_find_option_cstr2( "v1",NULL, NULL, ++argPos );
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
** line on the title bar. The "my" page was never completed so it is now
** removed. Use this page as a placeholder in older installations.
*/
void login_page(void){
const char *zUsername, *zPasswd;
const char *zNew1, *zNew2;
const char *zAnonPw = 0;
int anonFlag;
char *zErrMsg = "";
int uid; /* User id loged in user */
char *zSha1Pw;
const char *zIpAddr; /* IP address of requestor */
login_check_credentials();
| > | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
** line on the title bar. The "my" page was never completed so it is now
** removed. Use this page as a placeholder in older installations.
*/
void login_page(void){
const char *zUsername, *zPasswd;
const char *zNew1, *zNew2;
const char *zAnonPw = 0;
const char *zGoto = P("g");
int anonFlag;
char *zErrMsg = "";
int uid; /* User id loged in user */
char *zSha1Pw;
const char *zIpAddr; /* IP address of requestor */
login_check_credentials();
|
| ︙ | ︙ | |||
559 560 561 562 563 564 565 566 |
*/
login_set_user_cookie(zUsername, uid, NULL);
redirect_to_g();
}
}
style_header("Login/Logout");
@ %s(zErrMsg)
@ <form action="login" method="post">
| > > > | | | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 |
*/
login_set_user_cookie(zUsername, uid, NULL);
redirect_to_g();
}
}
style_header("Login/Logout");
@ %s(zErrMsg)
if( zGoto && P("anon")==0 ){
@ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p>
}
@ <form action="login" method="post">
if( zGoto ){
@ <input type="hidden" name="g" value="%h(zGoto)" />
}
@ <table class="login_out">
@ <tr>
@ <td class="login_out_label">User ID:</td>
if( anonFlag ){
@ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td>
}else{
|
| ︙ | ︙ | |||
588 589 590 591 592 593 594 | @ <tr> @ <td></td> @ <td><input type="submit" name="in" value="Login" @ onClick="chngAction(this.form)" /></td> @ </tr> @ </table> @ <script type="text/JavaScript"> | | | 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 |
@ <tr>
@ <td></td>
@ <td><input type="submit" name="in" value="Login"
@ onClick="chngAction(this.form)" /></td>
@ </tr>
@ </table>
@ <script type="text/JavaScript">
@ gebi('u').focus()
@ function chngAction(form){
if( g.sslNotAvailable==0
&& memcmp(g.zBaseURL,"https:",6)!=0
&& db_get_boolean("https-login",0)
){
char *zSSL = mprintf("https:%s", &g.zBaseURL[5]);
@ if( form.u.value!="anonymous" ){
|
| ︙ | ︙ | |||
629 630 631 632 633 634 635 |
@ Visitors may enter <b>anonymous</b> as the user-ID with
@ the 8-character hexadecimal password shown below:</p>
@ <div class="captcha"><table class="captcha"><tr><td><pre>
@ %s(zCaptcha)
@ </pre></td></tr></table>
if( bAutoCaptcha ) {
@ <input type="button" value="Fill out captcha"
| < | | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 |
@ Visitors may enter <b>anonymous</b> as the user-ID with
@ the 8-character hexadecimal password shown below:</p>
@ <div class="captcha"><table class="captcha"><tr><td><pre>
@ %s(zCaptcha)
@ </pre></td></tr></table>
if( bAutoCaptcha ) {
@ <input type="button" value="Fill out captcha"
@ onclick="gebi('u').value='anonymous'; gebi('p').value='%s(zDecoded)';" />
}
@ </div>
free(zCaptcha);
}
if( g.zLogin ){
@ <hr />
@ <p>To log off the system (and delete your login cookie)
|
| ︙ | ︙ | |||
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 |
}
/*
** This routine examines the login cookie to see if it exists and and
** is valid. If the login cookie checks out, it then sets global
** variables appropriately. Global variables set include g.userUid
** and g.zLogin and the g.perm family of permission booleans.
*/
void login_check_credentials(void){
int uid = 0; /* User id */
const char *zCookie; /* Text of the login cookie */
const char *zIpAddr; /* Raw IP address of the requestor */
char *zRemoteAddr; /* Abbreviated IP address of the requestor */
const char *zCap = 0; /* Capability string */
/* Only run this check once. */
if( g.userUid!=0 ) return;
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
| > > > | 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 |
}
/*
** This routine examines the login cookie to see if it exists and and
** is valid. If the login cookie checks out, it then sets global
** variables appropriately. Global variables set include g.userUid
** and g.zLogin and the g.perm family of permission booleans.
**
** If the
*/
void login_check_credentials(void){
int uid = 0; /* User id */
const char *zCookie; /* Text of the login cookie */
const char *zIpAddr; /* Raw IP address of the requestor */
char *zRemoteAddr; /* Abbreviated IP address of the requestor */
const char *zCap = 0; /* Capability string */
const char *zPublicPages = 0; /* GLOB patterns of public pages */
/* Only run this check once. */
if( g.userUid!=0 ) return;
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
|
| ︙ | ︙ | |||
902 903 904 905 906 907 908 |
if( fossil_strcmp(g.zLogin,"nobody")==0 ){
g.zLogin = 0;
}
/* Set the capabilities */
login_replace_capabilities(zCap, 0);
login_set_anon_nobody_capabilities();
| | > | > > > > > > > > > > > > > > | 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 |
if( fossil_strcmp(g.zLogin,"nobody")==0 ){
g.zLogin = 0;
}
/* Set the capabilities */
login_replace_capabilities(zCap, 0);
login_set_anon_nobody_capabilities();
if( zCap[0] && !g.perm.Hyperlink
&& db_get_boolean("auto-hyperlink",1)
&& isHuman(P("HTTP_USER_AGENT")) ){
g.perm.Hyperlink = 1;
g.javascriptHyperlink = 1;
}
/* If the public-pages glob pattern is defined and REQUEST_URI matches
** one of the globs in public-pages, then also add in all default-perms
** permissions.
*/
zPublicPages = db_get("public-pages",0);
if( zPublicPages!=0 ){
Glob *pGlob = glob_create(zPublicPages);
if( glob_match(pGlob, PD("REQUEST_URI","no-match")) ){
login_set_capabilities(db_get("default-perms","u"), 0);
}
glob_free(pGlob);
}
}
/*
** Memory of settings
*/
static int login_anon_once = 1;
|
| ︙ | ︙ | |||
951 952 953 954 955 956 957 |
if(NULL==zCap){
return;
}
for(i=0; zCap[i]; i++){
switch( zCap[i] ){
case 's': g.perm.Setup = 1; /* Fall thru into Admin */
case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip =
| | | | | | | | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 |
if(NULL==zCap){
return;
}
for(i=0; zCap[i]; i++){
switch( zCap[i] ){
case 's': g.perm.Setup = 1; /* Fall thru into Admin */
case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip =
g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki =
g.perm.ApndWiki = g.perm.Hyperlink = g.perm.Clone =
g.perm.NewTkt = g.perm.Password = g.perm.RdAddr =
g.perm.TktFmt = g.perm.Attach = g.perm.ApndTkt = 1;
/* Fall thru into Read/Write */
case 'i': g.perm.Read = g.perm.Write = 1; break;
case 'o': g.perm.Read = 1; break;
case 'z': g.perm.Zip = 1; break;
case 'd': g.perm.Delete = 1; break;
case 'h': g.perm.Hyperlink = 1; break;
case 'g': g.perm.Clone = 1; break;
case 'p': g.perm.Password = 1; break;
case 'j': g.perm.RdWiki = 1; break;
case 'k': g.perm.WrWiki = g.perm.RdWiki = g.perm.ApndWiki =1; break;
case 'm': g.perm.ApndWiki = 1; break;
case 'f': g.perm.NewWiki = 1; break;
|
| ︙ | ︙ | |||
1031 1032 1033 1034 1035 1036 1037 |
case 'a': rc = g.perm.Admin; break;
case 'b': rc = g.perm.Attach; break;
case 'c': rc = g.perm.ApndTkt; break;
case 'd': rc = g.perm.Delete; break;
case 'e': rc = g.perm.RdAddr; break;
case 'f': rc = g.perm.NewWiki; break;
case 'g': rc = g.perm.Clone; break;
| | < | 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 |
case 'a': rc = g.perm.Admin; break;
case 'b': rc = g.perm.Attach; break;
case 'c': rc = g.perm.ApndTkt; break;
case 'd': rc = g.perm.Delete; break;
case 'e': rc = g.perm.RdAddr; break;
case 'f': rc = g.perm.NewWiki; break;
case 'g': rc = g.perm.Clone; break;
case 'h': rc = g.perm.Hyperlink; break;
case 'i': rc = g.perm.Write; break;
case 'j': rc = g.perm.RdWiki; break;
case 'k': rc = g.perm.WrWiki; break;
case 'm': rc = g.perm.ApndWiki; break;
case 'n': rc = g.perm.NewTkt; break;
case 'o': rc = g.perm.Read; break;
case 'p': rc = g.perm.Password; break;
/* case 'q': */
case 'r': rc = g.perm.RdTkt; break;
case 's': rc = g.perm.Setup; break;
|
| ︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 |
cgi_redirect(mprintf("login?g=%T", zUrl));
/* NOTREACHED */
assert(0);
}
}
/*
| | | | | | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 |
cgi_redirect(mprintf("login?g=%T", zUrl));
/* NOTREACHED */
assert(0);
}
}
/*
** Call this routine if the user lacks g.perm.Hyperlink permission. If
** the anonymous user has Hyperlink permission, then paint a mesage
** to inform the user that much more information is available by
** logging in as anonymous.
*/
void login_anonymous_available(void){
if( !g.perm.Hyperlink &&
db_exists("SELECT 1 FROM user"
" WHERE login='anonymous'"
" AND cap LIKE '%%h%%'") ){
const char *zUrl = PD("REQUEST_URI", "index");
@ <p>Many <span class="disabled">hyperlinks are disabled.</span><br />
@ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
@ to enable hyperlinks.</p>
}
}
/*
** While rendering a form, call this routine to add the Anti-CSRF token
** as a hidden element of the form.
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | #include "main.h" #include <string.h> #include <time.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> /* atexit() */ | | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include "main.h" #include <string.h> #include <time.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> /* atexit() */ #if !defined(_WIN32) # include <errno.h> /* errno global */ #endif #if INTERFACE #ifdef FOSSIL_ENABLE_JSON # include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */ # include "json_detail.h" #endif #ifdef FOSSIL_ENABLE_TCL #include "tcl.h" |
| ︙ | ︙ | |||
58 59 60 61 62 63 64 | char Setup; /* s: use Setup screens on web interface */ char Admin; /* a: administrative permission */ char Delete; /* d: delete wiki or tickets */ char Password; /* p: change password */ char Query; /* q: create new reports */ char Write; /* i: xfer inbound. checkin */ char Read; /* o: xfer outbound. checkout */ | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | char Setup; /* s: use Setup screens on web interface */ char Admin; /* a: administrative permission */ char Delete; /* d: delete wiki or tickets */ char Password; /* p: change password */ char Query; /* q: create new reports */ char Write; /* i: xfer inbound. checkin */ char Read; /* o: xfer outbound. checkout */ char Hyperlink; /* h: enable the display of hyperlinks */ char Clone; /* g: clone */ char RdWiki; /* j: view wiki via web */ char NewWiki; /* f: create new wiki via web */ char ApndWiki; /* m: append to wiki via web */ char WrWiki; /* k: edit wiki via web */ char RdTkt; /* r: view tickets via web */ char NewTkt; /* n: create new tickets */ |
| ︙ | ︙ | |||
133 134 135 136 137 138 139 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ | | > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ char isHTTP; /* True if erver/CGI modes, else assume CLI. */ char javascriptHyperlink; /* If true, set href= using script, not HTML */ int urlIsFile; /* True if a "file:" url */ int urlIsHttps; /* True if a "https:" url */ int urlIsSsh; /* True if an "ssh:" url */ char *urlName; /* Hostname for http: or filename for file: */ char *urlHostname; /* The HOST: parameter on http headers */ char *urlProtocol; /* "http" or "https" */ |
| ︙ | ︙ | |||
240 241 242 243 244 245 246 |
cson_value * v;
cson_object * o;
} param;
struct {
cson_value * v;
cson_object * o;
} reqPayload; /* request payload object (if any) */
| < < | < | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
cson_value * v;
cson_object * o;
} param;
struct {
cson_value * v;
cson_object * o;
} reqPayload; /* request payload object (if any) */
cson_array * warnings; /* response warnings */
} json;
#endif /* FOSSIL_ENABLE_JSON */
};
/*
** Macro for debugging:
*/
|
| ︙ | ︙ | |||
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
fossil_print(
"Usage: %s COMMAND ...\n"
" or: %s help -- for a list of common commands\n"
" or: %s help COMMMAND -- for help with the named command\n",
argv[0], argv[0], argv[0]);
fossil_exit(1);
}else{
g.isHTTP = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
if( g.fSqlTrace ) g.fSqlStats = 1;
g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
g.zLogin = find_option("user", "U", 1);
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
if( find_option("help",0,0)!=0 ){
/* --help anywhere on the command line is translated into
** "fossil help argv[1] argv[2]..." */
int i;
char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) );
for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i];
zNewArgv[i+1] = 0;
| > > > > | 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 |
fossil_print(
"Usage: %s COMMAND ...\n"
" or: %s help -- for a list of common commands\n"
" or: %s help COMMMAND -- for help with the named command\n",
argv[0], argv[0], argv[0]);
fossil_exit(1);
}else{
const char *zChdir = find_option("chdir",0,1);
g.isHTTP = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
if( g.fSqlTrace ) g.fSqlStats = 1;
g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
g.zLogin = find_option("user", "U", 1);
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
if( zChdir && chdir(zChdir) ){
fossil_fatal("unable to change directories to %s", zChdir);
}
if( find_option("help",0,0)!=0 ){
/* --help anywhere on the command line is translated into
** "fossil help argv[1] argv[2]..." */
int i;
char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) );
for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i];
zNewArgv[i+1] = 0;
|
| ︙ | ︙ | |||
553 554 555 556 557 558 559 |
else
#endif
{
if( g.cgiOutput && once ){
once = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
| | | 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
else
#endif
{
if( g.cgiOutput && once ){
once = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
}else if( !g.fQuiet ){
char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z);
fossil_puts(zOut, 1);
}
}
free(z);
db_force_rollback();
fossil_exit(rc);
|
| ︙ | ︙ | |||
585 586 587 588 589 590 591 |
else
#endif
{
if( g.cgiOutput ){
g.cgiOutput = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
| | | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
else
#endif
{
if( g.cgiOutput ){
g.cgiOutput = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
}else if( !g.fQuiet ){
char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z);
fossil_puts(zOut, 1);
}
}
free(z);
db_force_rollback();
fossil_exit(rc);
|
| ︙ | ︙ | |||
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 |
if( fossil_stricmp(zMode,"on")==0 ){
g.zBaseURL = mprintf("https://%s%.*s", zHost, i, zCur);
g.zTop = &g.zBaseURL[8+strlen(zHost)];
}else{
g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur);
g.zTop = &g.zBaseURL[7+strlen(zHost)];
}
}
/*
** Send an HTTP redirect back to the designated Index Page.
*/
NORETURN void fossil_redirect_home(void){
cgi_redirectf("%s%s", g.zTop, db_get("index-page", "/index"));
| > > > > > > > > > > > | 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 |
if( fossil_stricmp(zMode,"on")==0 ){
g.zBaseURL = mprintf("https://%s%.*s", zHost, i, zCur);
g.zTop = &g.zBaseURL[8+strlen(zHost)];
}else{
g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur);
g.zTop = &g.zBaseURL[7+strlen(zHost)];
}
if( db_is_writeable("repository") ){
if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL)){
db_multi_exec("INSERT INTO config(name,value,mtime)"
"VALUES('baseurl:%q',1,now())", g.zBaseURL);
}else{
db_optional_sql("repository",
"REPLACE INTO config(name,value,mtime)"
"VALUES('baseurl:%q',1,now())", g.zBaseURL
);
}
}
}
/*
** Send an HTTP redirect back to the designated Index Page.
*/
NORETURN void fossil_redirect_home(void){
cgi_redirectf("%s%s", g.zTop, db_get("index-page", "/index"));
|
| ︙ | ︙ | |||
1133 1134 1135 1136 1137 1138 1139 |
}
zDir[i] = '/';
zRepo = &zDir[i];
}
if( stat(zRepo, &sStat)!=0 ){
fossil_fatal("cannot stat() repository: %s", zRepo);
}
| | | > > > | 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 |
}
zDir[i] = '/';
zRepo = &zDir[i];
}
if( stat(zRepo, &sStat)!=0 ){
fossil_fatal("cannot stat() repository: %s", zRepo);
}
i = setgid(sStat.st_gid);
i = i || setuid(sStat.st_uid);
if(i){
fossil_fatal("setgid/uid() failed with errno %d", errno);
}
if( g.db!=0 ){
db_close(1);
db_open_repository(zRepo);
}
}
#endif
return zRepo;
|
| ︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | #ifdef FOSSIL_ENABLE_JSON /* ** Workaround to allow us to customize some following behaviour for ** JSON mode. The problem is, we don't always know if we're in JSON ** mode at this point (namely, for GET mode we don't know but POST ** we do), so we snoop g.zPath and cheat a bit. */ | | | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 |
#ifdef FOSSIL_ENABLE_JSON
/*
** Workaround to allow us to customize some following behaviour for
** JSON mode. The problem is, we don't always know if we're in JSON
** mode at this point (namely, for GET mode we don't know but POST
** we do), so we snoop g.zPath and cheat a bit.
*/
if( !g.json.isJsonMode && g.zPath && (0==strncmp("json",g.zPath,4)) ){
g.json.isJsonMode = 1;
}
#endif
if( g.zExtra ){
/* CGI parameters get this treatment elsewhere, but places like getfile
** will use g.zExtra directly.
** Reminder: the login mechanism uses 'name' differently, and may
|
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
313 314 315 316 317 318 319 320 321 322 323 324 325 326 | APPNAME = fossil$(E) all: $(OBJDIR) $(APPNAME) install: $(APPNAME) mv $(APPNAME) $(INSTALLDIR) $(OBJDIR): -mkdir $(OBJDIR) $(OBJDIR)/translate: $(SRCDIR)/translate.c $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c | > | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | APPNAME = fossil$(E) all: $(OBJDIR) $(APPNAME) install: $(APPNAME) mkdir -p $(INSTALLDIR) mv $(APPNAME) $(INSTALLDIR) $(OBJDIR): -mkdir $(OBJDIR) $(OBJDIR)/translate: $(SRCDIR)/translate.c $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| ︙ | ︙ | |||
1063 1064 1065 1066 1067 1068 1069 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o $(OBJDIR)/th.o: $(SRCDIR)/th.c | | | | | | 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o $(OBJDIR)/th.o: $(SRCDIR)/th.c $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c $(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
writeln "APPNAME = $name\$(E)"
writeln "\n"
writeln {
all: $(OBJDIR) $(APPNAME)
install: $(APPNAME)
mv $(APPNAME) $(INSTALLDIR)
$(OBJDIR):
-mkdir $(OBJDIR)
$(OBJDIR)/translate: $(SRCDIR)/translate.c
$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
| > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
writeln "APPNAME = $name\$(E)"
writeln "\n"
writeln {
all: $(OBJDIR) $(APPNAME)
install: $(APPNAME)
mkdir -p $(INSTALLDIR)
mv $(APPNAME) $(INSTALLDIR)
$(OBJDIR):
-mkdir $(OBJDIR)
$(OBJDIR)/translate: $(SRCDIR)/translate.c
$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
|
| ︙ | ︙ | |||
287 288 289 290 291 292 293 |
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
set opt {-Dmain=sqlite3_shell}
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
| | | | | | 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 |
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
set opt {-Dmain=sqlite3_shell}
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"
writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n"
set opt {}
writeln {
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE
}
close $output_file
#
# End of the main.mk output
##############################################################################
##############################################################################
|
| ︙ | ︙ | |||
364 365 366 367 368 369 370 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # | | | | | | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # ZINCDIR = $(SRCDIR)/../zlib-1.2.7 ZLIBDIR = $(SRCDIR)/../zlib-1.2.7 #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLINCDIR = $(SRCDIR)/../openssl-1.0.1c/include OPENSSLLIBDIR = $(SRCDIR)/../openssl-1.0.1c #### Either the directory where the Tcl library is installed or the Tcl # source code directory resides (depending on the value of the macro # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, # this directory must have "include" and "lib" sub-directories. If # this points to the Tcl source code directory, this directory must # have "generic" and "win" sub-directories. The recommended usage |
| ︙ | ︙ | |||
414 415 416 417 418 419 420 | # the finished binary for fossil. The BCC compiler above is used # for building intermediate code-generator tools. # TCC = gcc -Os -Wall -L$(ZLIBDIR) -I$(ZINCDIR) # With HTTPS support ifdef FOSSIL_ENABLE_SSL | < | 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | # the finished binary for fossil. The BCC compiler above is used # for building intermediate code-generator tools. # TCC = gcc -Os -Wall -L$(ZLIBDIR) -I$(ZINCDIR) # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -L$(OPENSSLLIBDIR) -I$(OPENSSLINCDIR) endif # With Tcl support ifdef FOSSIL_ENABLE_TCL ifdef FOSSIL_TCL_SOURCE TCC += -L$(TCLSRCDIR)/win -I$(TCLSRCDIR)/generic -I$(TCLSRCDIR)/win |
| ︙ | ︙ | |||
504 505 506 507 508 509 510 |
writeln "\n"
writeln -nonewline "OBJ ="
foreach s [lsort $src] {
writeln -nonewline " \\\n \$(OBJDIR)/$s.o"
}
writeln "\n"
writeln "APPNAME = ${name}.exe"
| | | | | > | 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 |
writeln "\n"
writeln -nonewline "OBJ ="
foreach s [lsort $src] {
writeln -nonewline " \\\n \$(OBJDIR)/$s.o"
}
writeln "\n"
writeln "APPNAME = ${name}.exe"
writeln {TRANSLATE = $(OBJDIR)/translate.exe
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
MKINDEX = $(OBJDIR)/mkindex.exe
VERSION = $(OBJDIR)/version.exe
}
writeln {
all: $(OBJDIR) $(APPNAME)
$(OBJDIR)/icon.o: $(SRCDIR)/../win/icon.rc
cp $(SRCDIR)/../win/icon.rc $(OBJDIR)
windres $(OBJDIR)/icon.rc -o $(OBJDIR)/icon.o
install: $(APPNAME)
mkdir -p $(INSTALLDIR)
mv $(APPNAME) $(INSTALLDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OBJDIR)/translate: $(SRCDIR)/translate.c
$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
|
| ︙ | ︙ | |||
618 619 620 621 622 623 624 |
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
set opt {-Dmain=sqlite3_shell}
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
| | | | | 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 |
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
set opt {-Dmain=sqlite3_shell}
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"
writeln {ifdef FOSSIL_ENABLE_TCL
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
$(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o
endif
}
close $output_file
#
# End of the main.mk output
##############################################################################
|
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
972 973 974 975 976 977 978 979 980 981 982 983 984 985 |
}
blob_read_from_file(&b, g.argv[2]);
if( g.argc>3 ) n = atoi(g.argv[3]);
for(i=0; i<n; i++){
Blob b2;
blob_copy(&b2, &b);
p = manifest_parse(&b2, 0);
manifest_destroy(p);
}
}
/*
** Fetch the baseline associated with the delta-manifest p.
** Return 0 on success. If unable to parse the baseline,
| > | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
}
blob_read_from_file(&b, g.argv[2]);
if( g.argc>3 ) n = atoi(g.argv[3]);
for(i=0; i<n; i++){
Blob b2;
blob_copy(&b2, &b);
p = manifest_parse(&b2, 0);
if( p==0 ) fossil_print("FAILED!\n");
manifest_destroy(p);
}
}
/*
** Fetch the baseline associated with the delta-manifest p.
** Return 0 on success. If unable to parse the baseline,
|
| ︙ | ︙ |
Changes to src/md5.c.
| ︙ | ︙ | |||
262 263 264 265 266 267 268 |
/* Append length in bits and transform */
((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
MD5Transform(ctx->buf, (uint32 *)ctx->in);
byteReverse((unsigned char *)ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
| | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
/* Append length in bits and transform */
((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
MD5Transform(ctx->buf, (uint32 *)ctx->in);
byteReverse((unsigned char *)ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}
/*
** Convert a digest into base-16. digest should be declared as
** "unsigned char digest[16]" in the calling function. The MD5
** digest is stored in the first 16 bytes. zBuf should
** be "char zBuf[33]".
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
" WHERE tag.tagname='sym-%q' "
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
" AND event.objid=tagxref.rid "
" AND event.type GLOB '%q'"
" ORDER BY event.mtime DESC /*sort*/",
&zTag[4], zType
);
return rid;
}
/* symbolic-name ":" date-time */
nTag = strlen(zTag);
for(i=0; i<nTag-10 && zTag[i]!=':'; i++){}
if( zTag[i]==':' && is_date(&zTag[i+1]) ){
| > > > > > > > > > > > > > > > > > > > > > > > | 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 |
" WHERE tag.tagname='sym-%q' "
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
" AND event.objid=tagxref.rid "
" AND event.type GLOB '%q'"
" ORDER BY event.mtime DESC /*sort*/",
&zTag[4], zType
);
}
/* root:TAG -> The origin of the branch */
if( memcmp(zTag, "root:", 5)==0 ){
Stmt q;
int rc;
rid = symbolic_name_to_rid(zTag+5, zType);
db_prepare(&q,
"SELECT pid, EXISTS(SELECT 1 FROM tagxref"
" WHERE tagid=%d AND tagtype>0"
" AND value=%Q AND rid=plink.pid)"
" FROM plink"
" WHERE cid=:cid AND isprim",
TAG_BRANCH, &zTag[5]
);
do{
db_reset(&q);
db_bind_int(&q, ":cid", rid);
rc = db_step(&q);
if( rc!=SQLITE_ROW ) break;
rid = db_column_int(&q, 0);
}while( db_column_int(&q, 1)==1 && rid>0 );
db_finalize(&q);
return rid;
}
/* symbolic-name ":" date-time */
nTag = strlen(zTag);
for(i=0; i<nTag-10 && zTag[i]!=':'; i++){}
if( zTag[i]==':' && is_date(&zTag[i+1]) ){
|
| ︙ | ︙ |
Changes to src/path.c.
| ︙ | ︙ | |||
87 88 89 90 91 92 93 |
PathNode *p;
while( path.pAll ){
p = path.pAll;
path.pAll = p->pAll;
fossil_free(p);
}
bag_clear(&path.seen);
| | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
PathNode *p;
while( path.pAll ){
p = path.pAll;
path.pAll = p->pAll;
fossil_free(p);
}
bag_clear(&path.seen);
memset(&path, 0, sizeof(path));
}
/*
** Construct the path from path.pStart to path.pEnd in the u.pTo fields.
*/
static void path_reverse_path(void){
PathNode *p;
|
| ︙ | ︙ |
Changes to src/pqueue.c.
| ︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** value. We can insert integers with each integer tied to its ** value then extract the integer with the smallest value. ** ** The way this queue is used, we never expect it to contain more ** than 2 or 3 elements, so a simple array is sufficient as the ** implementation. This could give worst case O(N) insert times, ** but because of the nature of the problem we expect O(1) performance. */ #include "config.h" #include "pqueue.h" #include <assert.h> #if INTERFACE | > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ** value. We can insert integers with each integer tied to its ** value then extract the integer with the smallest value. ** ** The way this queue is used, we never expect it to contain more ** than 2 or 3 elements, so a simple array is sufficient as the ** implementation. This could give worst case O(N) insert times, ** but because of the nature of the problem we expect O(1) performance. ** ** Compatibility note: Some versions of OpenSSL export a symbols ** like "pqueue_insert". This is, technically, a bug in OpenSSL. ** We work around it here by using "pqueuex_" instead of "pqueue_". */ #include "config.h" #include "pqueue.h" #include <assert.h> #if INTERFACE |
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | } *a; }; #endif /* ** Initialize a PQueue structure */ | | | | | | | | | 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 |
} *a;
};
#endif
/*
** Initialize a PQueue structure
*/
void pqueuex_init(PQueue *p){
memset(p, 0, sizeof(*p));
}
/*
** Destroy a PQueue. Delete all of its content.
*/
void pqueuex_clear(PQueue *p){
free(p->a);
pqueuex_init(p);
}
/*
** Change the size of the queue so that it contains N slots
*/
static void pqueuex_resize(PQueue *p, int N){
p->a = fossil_realloc(p->a, sizeof(p->a[0])*N);
p->sz = N;
}
/*
** Insert element e into the queue.
*/
void pqueuex_insert(PQueue *p, int e, double v, void *pData){
int i, j;
if( p->cnt+1>p->sz ){
pqueuex_resize(p, p->cnt+5);
}
for(i=0; i<p->cnt; i++){
if( p->a[i].value>v ){
for(j=p->cnt; j>i; j--){
p->a[j] = p->a[j-1];
}
break;
}
}
p->a[i].id = e;
p->a[i].p = pData;
p->a[i].value = v;
p->cnt++;
}
/*
** Extract the first element from the queue (the element with
** the smallest value) and return its ID. Return 0 if the queue
** is empty.
*/
int pqueuex_extract(PQueue *p, void **pp){
int e, i;
if( p->cnt==0 ){
if( pp ) *pp = 0;
return 0;
}
e = p->a[0].id;
if( pp ) *pp = p->a[0].p;
for(i=0; i<p->cnt-1; i++){
p->a[i] = p->a[i+1];
}
p->cnt--;
return e;
}
|
Changes to src/printf.c.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ #define etFOSSILIZE 19 /* The fossil header encoding format. */ #define etPATH 20 /* Path type */ #define etWIKISTR 21 /* Wiki text rendered from a char*: %w */ #define etWIKIBLOB 22 /* Wiki text rendered from a Blob*: %W */ #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ /* ** An "etByte" is an 8-bit unsigned value. */ typedef unsigned char etByte; | > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ #define etFOSSILIZE 19 /* The fossil header encoding format. */ #define etPATH 20 /* Path type */ #define etWIKISTR 21 /* Wiki text rendered from a char*: %w */ #define etWIKIBLOB 22 /* Wiki text rendered from a Blob*: %W */ #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ #define etROOT 24 /* String value of g.zTop: % */ /* ** An "etByte" is an 8-bit unsigned value. */ typedef unsigned char etByte; |
| ︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
{ 'b', 0, 2, etBLOB, 0, 0 },
{ 'B', 0, 2, etBLOBSQL, 0, 0 },
{ 'w', 0, 2, etWIKISTR, 0, 0 },
{ 'W', 0, 2, etWIKIBLOB, 0, 0 },
{ 'h', 0, 4, etHTMLIZE, 0, 0 },
{ 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
{ 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
{ 'F', 0, 4, etFOSSILIZE, 0, 0 },
{ 'S', 0, 4, etSTRINGID, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
{ 'u', 10, 0, etRADIX, 0, 0 },
| > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
{ 'b', 0, 2, etBLOB, 0, 0 },
{ 'B', 0, 2, etBLOBSQL, 0, 0 },
{ 'w', 0, 2, etWIKISTR, 0, 0 },
{ 'W', 0, 2, etWIKIBLOB, 0, 0 },
{ 'h', 0, 4, etHTMLIZE, 0, 0 },
{ 'R', 0, 0, etROOT, 0, 0 },
{ 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
{ 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
{ 'F', 0, 4, etFOSSILIZE, 0, 0 },
{ 'S', 0, 4, etSTRINGID, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
{ 'u', 10, 0, etRADIX, 0, 0 },
|
| ︙ | ︙ | |||
568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
bufpt[i]='/';
}else{
bufpt[i]=e[i];
}
}
bufpt[length]='\0';
break;
}
case etSTRINGID: {
precision = 16;
/* Fall through */
}
case etSTRING:
case etDYNSTRING: {
| > > > > > | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
bufpt[i]='/';
}else{
bufpt[i]=e[i];
}
}
bufpt[length]='\0';
break;
}
case etROOT: {
bufpt = g.zTop ? g.zTop : "";
length = (int)strlen(bufpt);
break;
}
case etSTRINGID: {
precision = 16;
/* Fall through */
}
case etSTRING:
case etDYNSTRING: {
|
| ︙ | ︙ | |||
744 745 746 747 748 749 750 |
blob_append(pBlob,spaces,etSPACESIZE);
nspace -= etSPACESIZE;
}
if( nspace>0 ) blob_append(pBlob,spaces,nspace);
}
}
if( zExtra ){
| | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
blob_append(pBlob,spaces,etSPACESIZE);
nspace -= etSPACESIZE;
}
if( nspace>0 ) blob_append(pBlob,spaces,nspace);
}
}
if( zExtra ){
fossil_free(zExtra);
}
}/* End for loop over the format string */
return errorflag ? -1 : count;
} /* End of function */
/*
** Print into memory obtained from fossil_malloc().
*/
char *mprintf(const char *zFormat, ...){
va_list ap;
char *z;
va_start(ap,zFormat);
z = vmprintf(zFormat, ap);
va_end(ap);
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
54 55 56 57 58 59 60 |
}
rn = db_column_int(&q, 0);
cnt++;
blob_appendf(&ril, "<li>");
if( zTitle[0] == '_' ){
blob_appendf(&ril, "%s", zTitle);
} else {
| | | > | > | > | 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 |
}
rn = db_column_int(&q, 0);
cnt++;
blob_appendf(&ril, "<li>");
if( zTitle[0] == '_' ){
blob_appendf(&ril, "%s", zTitle);
} else {
blob_appendf(&ril, "%z%h</a>", href("%R/rptview?rn=%d", rn), zTitle);
}
blob_appendf(&ril, " ");
if( g.perm.Write && zOwner && zOwner[0] ){
blob_appendf(&ril, "(by <i>%h</i></i>) ", zOwner);
}
if( g.perm.TktFmt ){
blob_appendf(&ril, "[%zcopy</a>] ",
href("%R/rptedit?rn=%d©=1", rn));
}
if( g.perm.Admin
|| (g.perm.WrTkt && zOwner && fossil_strcmp(g.zLogin,zOwner)==0)
){
blob_appendf(&ril, "[%zedit</a>]",
href("%R/rptedit?rn=%d", rn));
}
if( g.perm.TktFmt ){
blob_appendf(&ril, "[%zsql</a>]",
href("%R/rptsql?rn=%d", rn));
}
blob_appendf(&ril, "</li>\n");
}
Th_Store("report_items", blob_str(&ril));
Th_Render(zScript);
|
| ︙ | ︙ | |||
414 415 416 417 418 419 420 |
zTitle = mprintf("Copy Of %s", zTitle);
zOwner = g.zLogin;
}
}
if( zOwner==0 ) zOwner = g.zLogin;
style_submenu_element("Cancel", "Cancel", "reportlist");
if( rn>0 ){
| | | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
zTitle = mprintf("Copy Of %s", zTitle);
zOwner = g.zLogin;
}
}
if( zOwner==0 ) zOwner = g.zLogin;
style_submenu_element("Cancel", "Cancel", "reportlist");
if( rn>0 ){
style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
}
style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
if( zErr ){
@ <blockquote class="reportError">%h(zErr)</blockquote>
}
@ <form action="rptedit" method="post"><div>
@ <input type="hidden" name="rn" value="%d(rn)" />
|
| ︙ | ︙ | |||
718 719 720 721 722 723 724 |
for(i=0; i<nArg; i++){
char *zData;
if( i==pState->iBg ) continue;
zData = azArg[i];
if( zData==0 ) zData = "";
if( pState->iNewRow>=0 && i>=pState->iNewRow ){
if( zTid && g.perm.Write ){
| | < < < | < | | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
for(i=0; i<nArg; i++){
char *zData;
if( i==pState->iBg ) continue;
zData = azArg[i];
if( zData==0 ) zData = "";
if( pState->iNewRow>=0 && i>=pState->iNewRow ){
if( zTid && g.perm.Write ){
@ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td>
zTid = 0;
}
if( zData[0] ){
Blob content;
@ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
blob_init(&content, zData, -1);
wiki_convert(&content, 0, 0);
blob_reset(&content);
}
}else if( azName[i][0]=='#' ){
zTid = zData;
@ <td valign="top">%z(href("%R/tktview?name=%h",zData))%h(zData)</a></td>
}else if( zData[0]==0 ){
@ <td valign="top"> </td>
}else{
@ <td valign="top">
@ %h(zData)
@ </td>
}
}
if( zTid && g.perm.Write ){
@ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td>
}
@ </tr>
return 0;
}
/*
** Output the text given in the argument. Convert tabs and newlines into
|
| ︙ | ︙ | |||
863 864 865 866 867 868 869 870 871 872 873 874 875 876 |
return SQLITE_OK;
}
if( !sqlite3_stmt_readonly(pStmt) ){
sqlite3_finalize(pStmt);
return SQLITE_ERROR;
}
nCol = sqlite3_column_count(pStmt);
azVals = fossil_malloc(2*nCol*sizeof(const char*) + 1);
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
if( azCols==0 ){
azCols = &azVals[nCol];
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
| > > > | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 |
return SQLITE_OK;
}
if( !sqlite3_stmt_readonly(pStmt) ){
sqlite3_finalize(pStmt);
return SQLITE_ERROR;
}
i = sqlite3_bind_parameter_index(pStmt, "$login");
if( i ) sqlite3_bind_text(pStmt, i, g.zLogin, -1, SQLITE_TRANSIENT);
nCol = sqlite3_column_count(pStmt);
azVals = fossil_malloc(2*nCol*sizeof(const char*) + 1);
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
if( azCols==0 ){
azCols = &azVals[nCol];
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
|
| ︙ | ︙ | |||
947 948 949 950 951 952 953 |
count = 0;
if( !tabs ){
struct GenerateHTML sState;
db_multi_exec("PRAGMA empty_result_callbacks=ON");
style_submenu_element("Raw", "Raw",
| | | 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 |
count = 0;
if( !tabs ){
struct GenerateHTML sState;
db_multi_exec("PRAGMA empty_result_callbacks=ON");
style_submenu_element("Raw", "Raw",
"rptview?tablist=1&%h", PD("QUERY_STRING",""));
if( g.perm.Admin
|| (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn);
}
if( g.perm.TktFmt ){
style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn);
}
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
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 |
"Select from a menu of prepackaged \"skins\" for the web interface");
setup_menu_entry("CSS", "setup_editcss",
"Edit the Cascading Style Sheet used by all pages of this repository");
setup_menu_entry("Header", "setup_header",
"Edit HTML text inserted at the top of every page");
setup_menu_entry("Footer", "setup_footer",
"Edit HTML text inserted at the bottom of every page");
setup_menu_entry("Logo", "setup_logo",
"Change the logo and background images for the server");
setup_menu_entry("Shunned", "shun",
"Show artifacts that are shunned by this repository");
setup_menu_entry("Log", "rcvfromlist",
"A record of received artifacts and their sources");
setup_menu_entry("User-Log", "access_log",
"A record of login attempts");
setup_menu_entry("Stats", "stat",
"Display repository statistics");
@ </table>
style_footer();
}
/*
** WEBPAGE: setup_ulist
**
** Show a list of users. Clicking on any user jumps to the edit
** screen for that user.
*/
void setup_ulist(void){
Stmt s;
login_check_credentials();
if( !g.perm.Admin ){
login_needed();
return;
}
style_submenu_element("Add", "Add User", "setup_uedit");
style_header("User List");
@ <table class="usetupLayoutTable">
@ <tr><td class="usetupColumnLayout">
@ <span class="note">Users:</span>
@ <table class="usetupUserList">
| > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > | > | | > | < < > | > > | | | 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 |
"Select from a menu of prepackaged \"skins\" for the web interface");
setup_menu_entry("CSS", "setup_editcss",
"Edit the Cascading Style Sheet used by all pages of this repository");
setup_menu_entry("Header", "setup_header",
"Edit HTML text inserted at the top of every page");
setup_menu_entry("Footer", "setup_footer",
"Edit HTML text inserted at the bottom of every page");
setup_menu_entry("Ad-Unit", "setup_adunit",
"Edit HTML text for an ad unit inserted after the menu bar");
setup_menu_entry("Logo", "setup_logo",
"Change the logo and background images for the server");
setup_menu_entry("Shunned", "shun",
"Show artifacts that are shunned by this repository");
setup_menu_entry("Log", "rcvfromlist",
"A record of received artifacts and their sources");
setup_menu_entry("User-Log", "access_log",
"A record of login attempts");
setup_menu_entry("Stats", "stat",
"Display repository statistics");
setup_menu_entry("SQL", "admin_sql",
"Enter raw SQL commands");
@ </table>
style_footer();
}
/*
** WEBPAGE: setup_ulist
**
** Show a list of users. Clicking on any user jumps to the edit
** screen for that user.
*/
void setup_ulist(void){
Stmt s;
int prevLevel = 0;
login_check_credentials();
if( !g.perm.Admin ){
login_needed();
return;
}
style_submenu_element("Add", "Add User", "setup_uedit");
style_header("User List");
@ <table class="usetupLayoutTable">
@ <tr><td class="usetupColumnLayout">
@ <span class="note">Users:</span>
@ <table class="usetupUserList">
prevLevel = 0;
db_prepare(&s,
"SELECT uid, login, cap, info, 1 FROM user"
" WHERE login IN ('anonymous','nobody','developer','reader') "
" UNION ALL "
"SELECT uid, login, cap, info, 2 FROM user"
" WHERE login NOT IN ('anonymous','nobody','developer','reader') "
"ORDER BY 5, 2"
);
while( db_step(&s)==SQLITE_ROW ){
int iLevel = db_column_int(&s, 4);
const char *zCap = db_column_text(&s, 2);
const char *zLogin = db_column_text(&s, 1);
if( iLevel>prevLevel ){
if( prevLevel>0 ){
@ <tr><td colspan="3"><hr></td></tr>
}
if( iLevel==1 ){
@ <tr>
@ <th class="usetupListUser"
@ style="text-align: right;padding-right: 20px;">Category</th>
@ <th class="usetupListCap"
@ style="text-align: center;padding-right: 15px;">Capabilities</th>
@ <th class="usetupListCon"
@ style="text-align: left;">Notes</th>
@ </tr>
}else{
@ <tr>
@ <th class="usetupListUser"
@ style="text-align: right;padding-right: 20px;">User ID</th>
@ <th class="usetupListCap"
@ style="text-align: center;padding-right: 15px;">Capabilities</th>
@ <th class="usetupListCon"
@ style="text-align: left;">Contact Info</th>
@ </tr>
}
prevLevel = iLevel;
}
@ <tr>
@ <td class="usetupListUser"
@ style="text-align: right;padding-right: 20px;white-space:nowrap;">
if( g.perm.Admin && (zCap[0]!='s' || g.perm.Setup) ){
@ <a href="setup_uedit?id=%d(db_column_int(&s,0))">
}
@ %h(zLogin)
if( g.perm.Admin ){
@ </a>
}
@ </td>
@ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td>
@ <td class="usetupListCon" style="text-align: left;">%h(db_column_text(&s,3))</td>
@ </tr>
|
| ︙ | ︙ | |||
513 514 515 516 517 518 519 520 |
@ <td class="usetupEditLabel">Contact Info:</td>
@ <td><input type="text" name="info" size="40" value="%h(zInfo)" /></td>
@ </tr>
@ <tr>
@ <td class="usetupEditLabel">Capabilities:</td>
@ <td>
#define B(x) inherit[x]
if( g.perm.Setup ){
| > | > | > | > | > | > | > | > | > > | > | > | > | > | > | > | > | > > | > | > | > | > | > | > | > > | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 |
@ <td class="usetupEditLabel">Contact Info:</td>
@ <td><input type="text" name="info" size="40" value="%h(zInfo)" /></td>
@ </tr>
@ <tr>
@ <td class="usetupEditLabel">Capabilities:</td>
@ <td>
#define B(x) inherit[x]
@ <table border=0><tr><td valign="top">
if( g.perm.Setup ){
@ <label><input type="checkbox" name="as"%s(oas) />%s(B('s'))Setup
@ </label><br />
}
@ <label><input type="checkbox" name="aa"%s(oaa) />%s(B('a'))Admin
@ </label><br />
@ <label><input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete
@ </label><br />
@ <label><input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email
@ </label><br />
@ <label><input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password
@ </label><br />
@ <label><input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In
@ </label><br />
@ <label><input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out
@ </label><br />
@ <label><input type="checkbox" name="ah"%s(oah) />%s(B('h'))Hyperlinks
@ </label><br />
@ </td><td><td width="40"></td><td valign="top">
@ <label><input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader
@ </label><br />
@ <label><input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer
@ </label><br />
@ <label><input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone
@ </label><br />
@ <label><input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki
@ </label><br />
@ <label><input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki
@ </label><br />
@ <label><input type="checkbox" name="am"%s(oam) />%s(B('m'))Append Wiki
@ </label><br />
@ <label><input type="checkbox" name="ak"%s(oak) />%s(B('k'))Write Wiki
@ </label><br />
@ <label><input type="checkbox" name="ab"%s(oab) />%s(B('b'))Attachments
@ </label><br />
@ </td><td><td width="40"></td><td valign="top">
@ <label><input type="checkbox" name="ar"%s(oar) />%s(B('r'))Read Ticket
@ </label><br />
@ <label><input type="checkbox" name="an"%s(oan) />%s(B('n'))New Ticket
@ </label><br />
@ <label><input type="checkbox" name="ac"%s(oac) />%s(B('c'))Append Ticket
@ </label><br />
@ <label><input type="checkbox" name="aw"%s(oaw) />%s(B('w'))Write Ticket
@ </label><br />
@ <label><input type="checkbox" name="at"%s(oat) />%s(B('t'))Ticket Report
@ </label><br />
@ <label><input type="checkbox" name="ax"%s(oax) />%s(B('x'))Private
@ </label><br />
@ <label><input type="checkbox" name="az"%s(oaz) />%s(B('z'))Download Zip
@ </label>
@ </td></tr></table>
@ </td>
@ </tr>
@ <tr>
@ <td align="right">Password:</td>
if( zPw[0] ){
/* Obscure the password for all users */
@ <td><input type="password" name="pw" value="**********" /></td>
|
| ︙ | ︙ | |||
623 624 625 626 627 628 629 | @ by anonymous users. This capability is intended for deletion of spam. @ The delete capability is only in effect for 24 hours after the item @ is first posted. The <span class="usertype">Setup</span> user can @ delete anything at any time. @ </p></li> @ @ <li><p> | | | | | | 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 | @ by anonymous users. This capability is intended for deletion of spam. @ The delete capability is only in effect for 24 hours after the item @ is first posted. The <span class="usertype">Setup</span> user can @ delete anything at any time. @ </p></li> @ @ <li><p> @ The <span class="capability">Hyperlinks</span> privilege allows a user @ to see most hyperlinks. This is recommended ON for most logged-in users @ but OFF for user "nobody" to avoid problems with spiders trying to walk @ every diff and annotation of every historical check-in and file. @ </p></li> @ @ <li><p> @ The <span class="capability">Zip</span> privilege allows a user to @ see the "download as ZIP" @ hyperlink and permits access to the <tt>/zip</tt> page. This allows @ users to download ZIP archives without granting other rights like @ <span class="capability">Read</span> or @ <span class="capability">Hyperlink</span>. The "z" privilege is recommended @ for user <span class="usertype">nobody</span> so that automatic package @ downloaders can obtain the sources without going through the login @ procedure. @ </p></li> @ @ <li><p> @ The <span class="capability">Check-in</span> privilege allows remote @ users to "push". The <span class="capability">Check-out</span> privilege |
| ︙ | ︙ | |||
702 703 704 705 706 707 708 | @ capabilities of the <span class="usertype">nobody</span> user are @ inherited by all users, regardless of whether or not they are logged in. @ To disable universal access to the repository, make sure no user named @ <span class="usertype">nobody</span> exists or that the @ <span class="usertype">nobody</span> user has no capabilities @ enabled. The password for <span class="usertype">nobody</span> is ignore. @ To avoid problems with spiders overloading the server, it is recommended | | | | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 | @ capabilities of the <span class="usertype">nobody</span> user are @ inherited by all users, regardless of whether or not they are logged in. @ To disable universal access to the repository, make sure no user named @ <span class="usertype">nobody</span> exists or that the @ <span class="usertype">nobody</span> user has no capabilities @ enabled. The password for <span class="usertype">nobody</span> is ignore. @ To avoid problems with spiders overloading the server, it is recommended @ that the <span class="capability">h</span> (Hyperlinks) capability be @ turned off for the <span class="usertype">nobody</span> user. @ </p></li> @ @ <li><p> @ Login is required for user <span class="usertype">anonymous</span> but the @ password is displayed on the login screen beside the password entry box @ so anybody who can read should be able to login as anonymous. @ On the other hand, spiders and web-crawlers will typically not |
| ︙ | ︙ | |||
889 890 891 892 893 894 895 | @ <p>Fossil tries to limit out-bound sync, clone, and pull packets @ to this many bytes, uncompressed. If the client requires more data @ than this, then the client will issue multiple HTTP requests. @ Values below 1 million are not recommended. 5 million is a @ reasonable number.</p> @ <hr /> | > | | | | > > | > | > > > > > > | > > > > > > > > > > | > > | | 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 |
@ <p>Fossil tries to limit out-bound sync, clone, and pull packets
@ to this many bytes, uncompressed. If the client requires more data
@ than this, then the client will issue multiple HTTP requests.
@ Values below 1 million are not recommended. 5 million is a
@ reasonable number.</p>
@ <hr />
onoff_attribute(
"Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
"auto-hyperlink", "autohyperlink", 1);
@ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
@ including user "nobody", as long as (1) the User-Agent string in the
@ HTTP header indicates that the request is coming from an actual human
@ being and not a a robot or spider and (2) the user agent is able to
@ run Javascript in order to set the href= attribute of hyperlinks. Bots
@ and spiders can specify whatever User-Agent string they that want and
@ they can run javascript just like browsers. But most bots don't go to
@ that much trouble so this is normally an effective defense.</p>
@
@ <p>You do not normally want a bot to walk your entire repository because
@ if it does, your server will end up computing diffs and annotations for
@ every historical version of every file and creating ZIPs and tarballs of
@ every historical check-in, which can use a lot of CPU and bandwidth
@ even for relatively small projects.</p>
@ <hr />
entry_attribute("Public pages", 30, "public-pages",
"pubpage", "");
@ <p>A comma-separated list of glob patterns for pages that are accessible
@ without needing a login and using the privileges given by the
@ "Default privileges" setting below. Example use case: Set this field
@ to "/doc/trunk/www/*" to give anonymous users read-only permission to the
@ latest version of the embedded documentation in the www/ folder without
@ allowing them to see the rest of the source code.
@ </p>
@ <hr />
onoff_attribute("Allow users to register themselves",
"self-register", "selfregister", 0);
@ <p>Allow users to register themselves through the HTTP UI.
@ The registration form always requires filling in a CAPTCHA
@ (<em>auto-captcha</em> setting is ignored). Still, bear in mind that anyone
@ can register under any user name. This option is useful for public projects
@ where you do not want everyone in any ticket discussion to be named
@ "Anonymous".</p>
@ <hr />
entry_attribute("Default privileges", 10, "default-perms",
"defaultperms", "u");
@ <p>Permissions given to users that... <ul><li>register themselves using
@ the self-registration procedure (if enabled), or <li>access "public"
@ pages identified by the public-pages glob pattern above, or <li>
@ are users newly created by the administrator.</ul>
@ </p>
@ <hr />
onoff_attribute("Show javascript button to fill in CAPTCHA",
"auto-captcha", "autocaptcha", 0);
@ <p>When enabled, a button appears on the login screen for user
@ "anonymous" that will automatically fill in the CAPTCHA password.
|
| ︙ | ︙ | |||
1106 1107 1108 1109 1110 1111 1112 |
if( pSet->versionable ){
@ (v)<br />
} else {
@ <br />
}
}
}
| | | > | > | 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 |
if( pSet->versionable ){
@ (v)<br />
} else {
@ <br />
}
}
}
@ </td><td style="width:50px;"></td><td valign="top">
for(pSet=ctrlSettings; pSet->name!=0; pSet++){
if( pSet->width!=0 ){
entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name,
pSet->var!=0 ? pSet->var : pSet->name,
(char*)pSet->def);
if( pSet->versionable ){
@ (v)<br />
} else {
@ <br />
}
}
}
@ </td></tr></table>
@ <p><input type="submit" name="submit" value="Apply Changes" /></p>
@ </div></form>
@ <p>Settings marked with (v) are 'versionable' and will be overridden
@ by the contents of files named <tt>.fossil-settings/PROPERTY</tt>.</p>
@ <hr /><p>
@ These settings work in the same way, as the <kbd>set</kbd>
@ commandline:<br />
@ </p><pre>%s(zHelp_setting_cmd)</pre>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_config
|
| ︙ | ︙ | |||
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 |
@ <a href="setup_header">header</a> editing screens.
@ <blockquote><pre>
@ %h(zDefaultFooter)
@ </pre></blockquote>
style_footer();
db_end_transaction(0);
}
/*
** WEBPAGE: setup_logo
*/
void setup_logo(void){
const char *zLogoMime = db_get("logo-mimetype","image/gif");
const char *aLogoImg = P("logoim");
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 |
@ <a href="setup_header">header</a> editing screens.
@ <blockquote><pre>
@ %h(zDefaultFooter)
@ </pre></blockquote>
style_footer();
db_end_transaction(0);
}
/*
** WEBPAGE: setup_adunit
*/
void setup_adunit(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed();
}
db_begin_transaction();
if( P("clear")!=0 ){
db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'");
}else{
textarea_attribute(0, 0, 0, "adunit", "adunit", "");
}
style_header("Edit Ad Unit");
@ <form action="%s(g.zTop)/setup_adunit" method="post"><div>
login_insert_csrf_secret();
@ <p>Edit HTML text for an ad unit that will be inserted after the
@ menu bar and above the content of every page.</p>
textarea_attribute("", 20, 80, "adunit", "adunit", "");
@ <br />
onoff_attribute("Omit ads to administrator",
"adunit-omit-if-admin", "oia", 0);
@ <br />
onoff_attribute("Omit ads to logged-in users",
"adunit-omit-if-user", "oiu", 0);
@ <br />
@ <input type="submit" name="submit" value="Apply Changes" />
@ <input type="submit" name="clear" value="Delete Ad-Unit" />
@ </div></form>
style_footer();
db_end_transaction(0);
}
/*
** WEBPAGE: setup_logo
*/
void setup_logo(void){
const char *zLogoMime = db_get("logo-mimetype","image/gif");
const char *aLogoImg = P("logoim");
|
| ︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 | @ @ <p><span class="note">Note:</span> Your browser has probably cached these @ images, so you may need to press the Reload button before changes will @ take effect. </p> style_footer(); db_end_transaction(0); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 |
@
@ <p><span class="note">Note:</span> Your browser has probably cached these
@ images, so you may need to press the Reload button before changes will
@ take effect. </p>
style_footer();
db_end_transaction(0);
}
/*
** WEBPAGE: admin_sql
**
** Run raw SQL commands against the database file using the web interface.
*/
void sql_page(void){
const char *zQ = P("q");
int go = P("go")!=0;
login_check_credentials();
if( !g.perm.Setup ){
login_needed();
}
db_begin_transaction();
style_header("Raw SQL Commands");
@ <p><b>Caution:</b> There are no restrictions on the SQL that can be
@ run by this page. You can do serious and irrepairable damage to the
@ repository. Proceed with extreme caution.</p>
@
@ <p>Database names:<ul><li>repository → %s(db_name("repository"))
if( g.configOpen ){
@ <li>config → %s(db_name("configdb"))
}
if( g.localOpen ){
@ <li>local-checkout → %s(db_name("localdb"))
}
@ </ul></p>
@
@ <form method="post" action="%s(g.zTop)/admin_sql">
login_insert_csrf_secret();
@ SQL:<br />
@ <textarea name="q" rows="5" cols="80">%h(zQ)</textarea><br />
@ <input type="submit" name="go" value="Run SQL">
@ <input type="submit" name="schema" value="Show Schema">
@ <input type="submit" name="tablelist" value="List Tables">
@ </form>
if( P("schema") ){
zQ = sqlite3_mprintf(
"SELECT sql FROM %s.sqlite_master WHERE sql IS NOT NULL",
db_name("repository"));
go = 1;
}else if( P("tablelist") ){
zQ = sqlite3_mprintf(
"SELECT name FROM %s.sqlite_master WHERE type='table'"
" ORDER BY name",
db_name("repository"));
go = 1;
}
if( go ){
sqlite3_stmt *pStmt;
int rc;
const char *zTail;
int nCol;
int nRow = 0;
int i;
@ <hr />
login_verify_csrf_secret();
rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail);
if( rc!=SQLITE_OK ){
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
sqlite3_finalize(pStmt);
}else if( pStmt==0 ){
/* No-op */
}else if( (nCol = sqlite3_column_count(pStmt))==0 ){
sqlite3_step(pStmt);
rc = sqlite3_finalize(pStmt);
if( rc ){
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
}
}else{
@ <table border=1>
while( sqlite3_step(pStmt)==SQLITE_ROW ){
if( nRow==0 ){
@ <tr>
for(i=0; i<nCol; i++){
@ <th>%h(sqlite3_column_name(pStmt, i))</th>
}
@ </tr>
}
nRow++;
@ <tr>
for(i=0; i<nCol; i++){
switch( sqlite3_column_type(pStmt, i) ){
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
@ <td align="right" valign="top">
@ %s(sqlite3_column_text(pStmt, i))</td>
break;
}
case SQLITE_NULL: {
@ <td valign="top" align="center"><i>NULL</i></td>
break;
}
case SQLITE_TEXT: {
const char *zText = (const char*)sqlite3_column_text(pStmt, i);
@ <td align="left" valign="top"
@ style="white-space:pre;">%h(zText)</td>
break;
}
case SQLITE_BLOB: {
@ <td valign="top" align="center">
@ <i>%d(sqlite3_column_bytes(pStmt, i))-byte BLOB</i></td>
break;
}
}
}
@ </tr>
}
sqlite3_finalize(pStmt);
@ </table>
}
}
style_footer();
}
|
Changes to src/shell.c.
| ︙ | ︙ | |||
32 33 34 35 36 37 38 | #include <string.h> #include <stdio.h> #include <assert.h> #include "sqlite3.h" #include <ctype.h> #include <stdarg.h> | | < < < < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include <string.h> #include <stdio.h> #include <assert.h> #include "sqlite3.h" #include <ctype.h> #include <stdarg.h> #if !defined(_WIN32) && !defined(WIN32) # include <signal.h> # if !defined(__RTP__) && !defined(_WRS_KERNEL) # include <pwd.h> # endif # include <unistd.h> # include <sys/types.h> #endif #ifdef HAVE_EDITLINE # include <editline/editline.h> #endif #if defined(HAVE_READLINE) && HAVE_READLINE==1 # include <readline/readline.h> # include <readline/history.h> #endif |
| ︙ | ︙ | |||
88 89 90 91 92 93 94 | static int enableTimer = 0; /* ctype macros that work with signed characters */ #define IsSpace(X) isspace((unsigned char)X) #define IsDigit(X) isdigit((unsigned char)X) #define ToLower(X) (char)tolower((unsigned char)X) | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | static int enableTimer = 0; /* ctype macros that work with signed characters */ #define IsSpace(X) isspace((unsigned char)X) #define IsDigit(X) isdigit((unsigned char)X) #define ToLower(X) (char)tolower((unsigned char)X) #if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) #include <sys/time.h> #include <sys/resource.h> /* Saved resource information for the beginning of an operation */ static struct rusage sBegin; /* |
| ︙ | ︙ | |||
495 496 497 498 499 500 501 |
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
int i;
char *zBlob = (char *)pBlob;
fprintf(out,"X'");
| | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
int i;
char *zBlob = (char *)pBlob;
fprintf(out,"X'");
for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
fprintf(out,"'");
}
/*
** Output the given string as a quoted string using SQL quoting conventions.
*/
static void output_quoted_string(FILE *out, const char *z){
|
| ︙ | ︙ | |||
2180 2181 2182 2183 2184 2185 2186 |
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
rc = SQLITE_OK;
}else{
zShellStatic = azArg[1];
rc = sqlite3_exec(p->db,
"SELECT sql FROM "
| | | | > | | | > | 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 |
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
rc = SQLITE_OK;
}else{
zShellStatic = azArg[1];
rc = sqlite3_exec(p->db,
"SELECT sql FROM "
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE lower(tbl_name) LIKE shellstatic()"
" AND type!='meta' AND sql NOTNULL "
"ORDER BY substr(type,2,1), "
" CASE type WHEN 'view' THEN rowid ELSE name END",
callback, &data, &zErrMsg);
zShellStatic = 0;
}
}else{
rc = sqlite3_exec(p->db,
"SELECT sql FROM "
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
"ORDER BY substr(type,2,1),"
" CASE type WHEN 'view' THEN rowid ELSE name END",
callback, &data, &zErrMsg
);
}
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
|
| ︙ | ︙ | |||
2244 2245 2246 2247 2248 2249 2250 2251 |
}else
if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
p->statsOn = booleanValue(azArg[1]);
}else
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
char **azResult;
| > | | > > | | | | > > > > > > > | | | > | < < | < | < < | | | > > > > > | > > > > | | > | > > > > > > | | | > | > > > | > | | < | < | | > | | 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 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 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 |
}else
if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
p->statsOn = booleanValue(azArg[1]);
}else
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
sqlite3_stmt *pStmt;
char **azResult;
int nRow, nAlloc;
char *zSql = 0;
int ii;
open_db(p);
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ) return rc;
zSql = sqlite3_mprintf(
"SELECT name FROM sqlite_master"
" WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%%'"
" AND name LIKE ?1");
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
if( strcmp(zDbName,"temp")==0 ){
zSql = sqlite3_mprintf(
"%z UNION ALL "
"SELECT 'temp.' || name FROM sqlite_temp_master"
" WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%%'"
" AND name LIKE ?1", zSql);
}else{
zSql = sqlite3_mprintf(
"%z UNION ALL "
"SELECT '%q.' || name FROM \"%w\".sqlite_master"
" WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%%'"
" AND name LIKE ?1", zSql, zDbName, zDbName);
}
}
sqlite3_finalize(pStmt);
zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ) return rc;
nRow = nAlloc = 0;
azResult = 0;
if( nArg>1 ){
sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
}else{
sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
}
while( sqlite3_step(pStmt)==SQLITE_ROW ){
if( nRow>=nAlloc ){
char **azNew;
int n = nAlloc*2 + 10;
azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
if( azNew==0 ){
fprintf(stderr, "Error: out of memory\n");
break;
}
nAlloc = n;
azResult = azNew;
}
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
if( azResult[nRow] ) nRow++;
}
sqlite3_finalize(pStmt);
if( nRow>0 ){
int len, maxlen = 0;
int i, j;
int nPrintCol, nPrintRow;
for(i=0; i<nRow; i++){
len = strlen30(azResult[i]);
if( len>maxlen ) maxlen = len;
}
nPrintCol = 80/(maxlen+2);
if( nPrintCol<1 ) nPrintCol = 1;
nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
for(i=0; i<nPrintRow; i++){
for(j=i; j<nRow; j+=nPrintRow){
char *zSp = j<nPrintRow ? "" : " ";
printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
}
printf("\n");
}
}
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
sqlite3_free(azResult);
}else
if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
static const struct {
const char *zCtrlName; /* Name of a test-control option */
int ctrlCode; /* Integer code for that option */
} aCtrl[] = {
|
| ︙ | ︙ | |||
2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 |
if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
&& nArg==2
){
enableTimer = booleanValue(azArg[1]);
}else
if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
output_file_close(p->traceOut);
p->traceOut = output_file_open(azArg[1]);
#ifndef SQLITE_OMIT_TRACE
if( p->traceOut==0 ){
sqlite3_trace(p->db, 0, 0);
}else{
sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
| > | 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 |
if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
&& nArg==2
){
enableTimer = booleanValue(azArg[1]);
}else
if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
open_db(p);
output_file_close(p->traceOut);
p->traceOut = output_file_open(azArg[1]);
#ifndef SQLITE_OMIT_TRACE
if( p->traceOut==0 ){
sqlite3_trace(p->db, 0, 0);
}else{
sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
|
| ︙ | ︙ | |||
2568 2569 2570 2571 2572 2573 2574 |
int startline = 0;
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
fflush(p->out);
free(zLine);
zLine = one_input_line(zSql, in);
if( zLine==0 ){
| > > | | 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 |
int startline = 0;
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
fflush(p->out);
free(zLine);
zLine = one_input_line(zSql, in);
if( zLine==0 ){
/* End of input */
if( stdin_is_interactive ) printf("\n");
break;
}
if( seenInterrupt ){
if( in!=0 ) break;
seenInterrupt = 0;
}
lineno++;
if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
|
| ︙ | ︙ | |||
2661 2662 2663 2664 2665 2666 2667 |
** Return a pathname which is the user's home directory. A
** 0 return indicates an error of some kind.
*/
static char *find_home_dir(void){
static char *home_dir = NULL;
if( home_dir ) return home_dir;
| | > | | | | > | | | 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 |
** Return a pathname which is the user's home directory. A
** 0 return indicates an error of some kind.
*/
static char *find_home_dir(void){
static char *home_dir = NULL;
if( home_dir ) return home_dir;
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
{
struct passwd *pwent;
uid_t uid = getuid();
if( (pwent=getpwuid(uid)) != NULL) {
home_dir = pwent->pw_dir;
}
}
#endif
#if defined(_WIN32_WCE)
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
*/
home_dir = "/";
#else
#if defined(_WIN32) || defined(WIN32)
if (!home_dir) {
home_dir = getenv("USERPROFILE");
}
#endif
if (!home_dir) {
home_dir = getenv("HOME");
}
#if defined(_WIN32) || defined(WIN32)
if (!home_dir) {
char *zDrive, *zPath;
int n;
zDrive = getenv("HOMEDRIVE");
zPath = getenv("HOMEPATH");
if( zDrive && zPath ){
n = strlen30(zDrive) + strlen30(zPath) + 1;
|
| ︙ | ︙ | |||
2901 2902 2903 2904 2905 2906 2907 |
}else{
fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
exit(1);
}
}
}
if( i<argc ){
| < < < < | 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 |
}else{
fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
exit(1);
}
}
}
if( i<argc ){
data.zDbFilename = argv[i++];
}else{
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";
#else
data.zDbFilename = 0;
#endif
/***** Begin Fossil Patch *****/
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | 1 2 3 4 5 6 7 8 9 10 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.7.14. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other |
| ︙ | ︙ | |||
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | /* ** Exactly one of the following macros must be defined in order to ** specify which memory allocation subsystem to use. ** ** SQLITE_SYSTEM_MALLOC // Use normal system malloc() ** SQLITE_WIN32_MALLOC // Use Win32 native heap API ** SQLITE_MEMDEBUG // Debugging version of system malloc() ** ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the ** assert() macro is enabled, each call into the Win32 native heap subsystem ** will cause HeapValidate to be called. If heap validation should fail, an ** assertion will be triggered. ** ** (Historical note: There used to be several other options, but we've ** pared it down to just these three.) ** ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. */ | > | > > > | > | > | > > > | 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 | /* ** Exactly one of the following macros must be defined in order to ** specify which memory allocation subsystem to use. ** ** SQLITE_SYSTEM_MALLOC // Use normal system malloc() ** SQLITE_WIN32_MALLOC // Use Win32 native heap API ** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails ** SQLITE_MEMDEBUG // Debugging version of system malloc() ** ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the ** assert() macro is enabled, each call into the Win32 native heap subsystem ** will cause HeapValidate to be called. If heap validation should fail, an ** assertion will be triggered. ** ** (Historical note: There used to be several other options, but we've ** pared it down to just these three.) ** ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. */ #if defined(SQLITE_SYSTEM_MALLOC) \ + defined(SQLITE_WIN32_MALLOC) \ + defined(SQLITE_ZERO_MALLOC) \ + defined(SQLITE_MEMDEBUG)>1 # error "Two or more of the following compile-time configuration options\ are defined but at most one is allowed:\ SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\ SQLITE_ZERO_MALLOC" #endif #if defined(SQLITE_SYSTEM_MALLOC) \ + defined(SQLITE_WIN32_MALLOC) \ + defined(SQLITE_ZERO_MALLOC) \ + defined(SQLITE_MEMDEBUG)==0 # define SQLITE_SYSTEM_MALLOC 1 #endif /* ** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the ** sizes of memory allocations below this value where possible. */ |
| ︙ | ︙ | |||
439 440 441 442 443 444 445 | ** The TCL headers are only needed when compiling the TCL bindings. */ #if defined(SQLITE_TCL) || defined(TCLSH) # include <tcl.h> #endif /* | > > | > | > | | > > > | 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 | ** The TCL headers are only needed when compiling the TCL bindings. */ #if defined(SQLITE_TCL) || defined(TCLSH) # include <tcl.h> #endif /* ** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that ** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, ** make it true by defining or undefining NDEBUG. ** ** Setting NDEBUG makes the code smaller and run faster by disabling the ** number assert() statements in the code. So we want the default action ** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG ** is set. Thus NDEBUG becomes an opt-in rather than an opt-out ** feature. */ #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif #if defined(NDEBUG) && defined(SQLITE_DEBUG) # undef NDEBUG #endif /* ** The testcase() macro is used to aid in coverage testing. When ** doing coverage testing, the condition inside the argument to ** testcase() must be evaluated both true and false in order to ** get full branch coverage. The testcase() macro is inserted |
| ︙ | ︙ | |||
653 654 655 656 657 658 659 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.14" #define SQLITE_VERSION_NUMBER 3007014 #define SQLITE_SOURCE_ID "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242" /* ** 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 |
| ︙ | ︙ | |||
765 766 767 768 769 770 771 |
** CAPI3REF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite3". It is useful to think of an sqlite3
** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
| > | | 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 |
** CAPI3REF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite3". It is useful to think of an sqlite3
** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
** and [sqlite3_close_v2()] are its destructors. There are many other
** interfaces (such as
** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
** [sqlite3_busy_timeout()] to name but three) that are methods on an
** sqlite3 object.
*/
typedef struct sqlite3 sqlite3;
/*
|
| ︙ | ︙ | |||
812 813 814 815 816 817 818 | #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** | > | | | > > > > > > > > > > > > | | > | | | > > | | > | | | > | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 | #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** ** ^If the database connection is associated with unfinalized prepared ** statements or unfinished sqlite3_backup objects then sqlite3_close() ** will leave the database connection open and return [SQLITE_BUSY]. ** ^If sqlite3_close_v2() is called with unfinalized prepared statements ** and unfinished sqlite3_backups, then the database connection becomes ** an unusable "zombie" which will automatically be deallocated when the ** last prepared statement is finalized or the last sqlite3_backup is ** finished. The sqlite3_close_v2() interface is intended for use with ** host languages that are garbage collected, and where the order in which ** destructors are called is arbitrary. ** ** Applications should [sqlite3_finalize | finalize] all [prepared statements], ** [sqlite3_blob_close | close] all [BLOB handles], and ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated ** with the [sqlite3] object prior to attempting to close the object. ^If ** sqlite3_close() is called on a [database connection] that still has ** outstanding [prepared statements], [BLOB handles], and/or ** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation ** of resources is deferred until all [prepared statements], [BLOB handles], ** and [sqlite3_backup] objects are also destroyed. ** ** ^If an [sqlite3] object is destroyed while a transaction is open, ** the transaction is automatically rolled back. ** ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ SQLITE_API int sqlite3_close(sqlite3*); SQLITE_API int sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ typedef int (*sqlite3_callback)(void*,int,char**, char**); |
| ︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ | > > | 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ |
| ︙ | ︙ | |||
1317 1318 1319 1320 1321 1322 1323 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the | | | 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary ** write ahead log and shared memory files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to |
| ︙ | ︙ | |||
2714 2715 2716 2717 2718 2719 2720 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** | | | | | 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** ** Prior to SQLite version 3.7.10, the Windows OS interface layer called ** the system malloc() and free() directly when converting ** filenames between the UTF-8 encoding used by SQLite ** and whatever filename encoding is used by the particular Windows ** installation. Memory allocation errors were detected, but ** they were reported back as [SQLITE_CANTOPEN] or ** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. ** ** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] ** must be either NULL or else pointers obtained from a prior ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** |
| ︙ | ︙ | |||
3120 3121 3122 3123 3124 3125 3126 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** | | | > | > | | | | 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw", ** "rwc", or "memory". Attempting to set it to any other value is ** an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is ** set to "memory" then a pure [in-memory database] that never reads ** or writes from disk is used. ^It is an error to specify a value for ** the mode parameter that is less restrictive than that specified by ** the flags passed in the third parameter to sqlite3_open_v2(). ** ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| ︙ | ︙ | |||
4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_temp_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_temp_directory;
/*
** CAPI3REF: Name Of The Folder Holding Database Files
**
** ^(If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all database files
** specified with a relative pathname and created or accessed by
** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed
** to be relative to that directory.)^ ^If this variable is a NULL
** pointer, then SQLite assumes that all database files specified
** with a relative pathname are relative to the current directory
** for the process. Only the windows VFS makes use of this global
** variable; it is ignored by the unix VFS.
**
** Changing the value of this variable while a database connection is
** open can result in a corrupt database.
**
** It is not safe to read or modify this variable in more than one
** thread at a time. It is not safe to read or modify this variable
** if a [database connection] is being used at the same time in a separate
** thread.
** It is intended that this variable be set once
** as part of process initialization and before any SQLite interface
** routines have been called and that this variable remain unchanged
** thereafter.
**
** ^The [data_store_directory pragma] may modify this variable and cause
** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
** the [data_store_directory pragma] always assumes that any string
** that this variable points to is held in memory obtained from
** [sqlite3_malloc] and the pragma may attempt to free that memory
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
|
| ︙ | ︙ | |||
5172 5173 5174 5175 5176 5177 5178 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache | < | 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache ** ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** ** ^Cache sharing is enabled and disabled for an entire process. |
| ︙ | ︙ | |||
6000 6001 6002 6003 6004 6005 6006 | ** ** The SQLite source code contains multiple implementations ** of these mutex routines. An appropriate implementation ** is selected automatically at compile-time. ^(The following ** implementations are available in the SQLite core: ** ** <ul> | < | | | | 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 | ** ** The SQLite source code contains multiple implementations ** of these mutex routines. An appropriate implementation ** is selected automatically at compile-time. ^(The following ** implementations are available in the SQLite core: ** ** <ul> ** <li> SQLITE_MUTEX_PTHREADS ** <li> SQLITE_MUTEX_W32 ** <li> SQLITE_MUTEX_NOOP ** </ul>)^ ** ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines ** that does no real locking and is appropriate for use in ** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix ** and Windows. ** ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex ** implementation is included with the library. In this case the ** application must supply a custom mutex implementation using the ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function ** before calling sqlite3_initialize() or any other public sqlite3_ |
| ︙ | ︙ | |||
6560 6561 6562 6563 6564 6565 6566 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect | | | 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 |
| ︙ | ︙ | |||
9011 9012 9013 9014 9015 9016 9017 | SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); #endif /* Functions used to query pager state and configuration. */ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); | | | 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 | SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); #endif /* Functions used to query pager state and configuration. */ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int); SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); |
| ︙ | ︙ | |||
9239 9240 9241 9242 9243 9244 9245 | */ #ifndef _SQLITE_OS_H_ #define _SQLITE_OS_H_ /* ** Figure out if we are dealing with Unix, Windows, or some other ** operating system. After the following block of preprocess macros, | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 | */ #ifndef _SQLITE_OS_H_ #define _SQLITE_OS_H_ /* ** Figure out if we are dealing with Unix, Windows, or some other ** operating system. After the following block of preprocess macros, ** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER ** will defined to either 1 or 0. One of the four will be 1. The other ** three will be 0. */ #if defined(SQLITE_OS_OTHER) # if SQLITE_OS_OTHER==1 # undef SQLITE_OS_UNIX # define SQLITE_OS_UNIX 0 # undef SQLITE_OS_WIN # define SQLITE_OS_WIN 0 # else # undef SQLITE_OS_OTHER # endif #endif #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) # define SQLITE_OS_OTHER 0 # ifndef SQLITE_OS_WIN # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) # define SQLITE_OS_WIN 1 # define SQLITE_OS_UNIX 0 # else # define SQLITE_OS_WIN 0 # define SQLITE_OS_UNIX 1 # endif # else # define SQLITE_OS_UNIX 0 # endif #else # ifndef SQLITE_OS_WIN # define SQLITE_OS_WIN 0 # endif #endif #if SQLITE_OS_WIN # include <windows.h> #endif /* ** Determine if we are dealing with Windows NT. ** ** We ought to be able to determine if we are compiling for win98 or winNT ** using the _WIN32_WINNT macro as follows: |
| ︙ | ︙ | |||
9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 | */ #if defined(_WIN32_WCE) # define SQLITE_OS_WINCE 1 #else # define SQLITE_OS_WINCE 0 #endif /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ #ifndef SET_FULLSYNC # define SET_FULLSYNC(x,y) #endif | > > > > > > > > > > > > > > > > | 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 | */ #if defined(_WIN32_WCE) # define SQLITE_OS_WINCE 1 #else # define SQLITE_OS_WINCE 0 #endif /* ** Determine if we are dealing with WindowsRT (Metro) as this has a different and ** incompatible API from win32. */ #if !defined(SQLITE_OS_WINRT) # define SQLITE_OS_WINRT 0 #endif /* ** When compiled for WinCE or WinRT, there is no concept of the current ** directory. */ #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT # define SQLITE_CURDIR 1 #endif /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ #ifndef SET_FULLSYNC # define SET_FULLSYNC(x,y) #endif |
| ︙ | ︙ | |||
9558 9559 9560 9561 9562 9563 9564 | ** mutual exclusion is provided. But this ** implementation can be overridden at ** start-time. ** ** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. ** ** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. | < < < < | 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 | ** mutual exclusion is provided. But this ** implementation can be overridden at ** start-time. ** ** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. ** ** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. */ #if !SQLITE_THREADSAFE # define SQLITE_MUTEX_OMIT #endif #if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) # if SQLITE_OS_UNIX # define SQLITE_MUTEX_PTHREADS # elif SQLITE_OS_WIN # define SQLITE_MUTEX_W32 # else # define SQLITE_MUTEX_NOOP # endif #endif #ifdef SQLITE_MUTEX_OMIT /* |
| ︙ | ︙ | |||
9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 | ** than being distinct from one another. */ #define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ #define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ #define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ #define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ #define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ /* ** Each SQL function is defined by an instance of the following ** structure. A pointer to this structure is stored in the sqlite.aFunc ** hash table. When multiple functions have the same name, the hash table ** points to a linked list of these structures. */ | > | 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 | ** than being distinct from one another. */ #define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ #define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ #define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ #define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ #define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ #define SQLITE_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */ /* ** Each SQL function is defined by an instance of the following ** structure. A pointer to this structure is stored in the sqlite.aFunc ** hash table. When multiple functions have the same name, the hash table ** points to a linked list of these structures. */ |
| ︙ | ︙ | |||
10930 10931 10932 10933 10934 10935 10936 10937 10938 |
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
ExprList *pEList; /* Optional list of named expressions */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
| > > < < | < < > > > > > > > > | 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 11013 11014 11015 11016 |
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
ExprList *pEList; /* Optional list of named expressions */
AggInfo *pAggInfo; /* Information about aggregates at this level */
NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
u8 ncFlags; /* Zero or more NC_* flags defined below */
};
/*
** Allowed values for the NameContext, ncFlags field.
*/
#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
** limit and nOffset to the value of the offset (or 0 if there is not
|
| ︙ | ︙ | |||
11620 11621 11622 11623 11624 11625 11626 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); | > | > | 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int); SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*); SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int); SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*); SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); |
| ︙ | ︙ | |||
11744 11745 11746 11747 11748 11749 11750 11751 11752 11753 11754 11755 11756 11757 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*); SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*); SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*); SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); | > | 11810 11811 11812 11813 11814 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*); SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*); SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*); SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); |
| ︙ | ︙ | |||
12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 | # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) #else SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); SQLITE_PRIVATE void sqlite3VtabLock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); | > | 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 12105 12106 | # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) #else SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p); SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); SQLITE_PRIVATE void sqlite3VtabLock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); |
| ︙ | ︙ | |||
12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 | "CASE_SENSITIVE_LIKE", #endif #ifdef SQLITE_CHECK_PAGES "CHECK_PAGES", #endif #ifdef SQLITE_COVERAGE_TEST "COVERAGE_TEST", #endif #ifdef SQLITE_DEBUG "DEBUG", #endif #ifdef SQLITE_DEFAULT_LOCKING_MODE "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), #endif | > > > | 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 | "CASE_SENSITIVE_LIKE", #endif #ifdef SQLITE_CHECK_PAGES "CHECK_PAGES", #endif #ifdef SQLITE_COVERAGE_TEST "COVERAGE_TEST", #endif #ifdef SQLITE_CURDIR "CURDIR", #endif #ifdef SQLITE_DEBUG "DEBUG", #endif #ifdef SQLITE_DEFAULT_LOCKING_MODE "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), #endif |
| ︙ | ︙ | |||
17645 17646 17647 17648 17649 17650 17651 |
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
return sqlite3NoopMutex();
}
#endif /* defined(SQLITE_MUTEX_NOOP) */
#endif /* !defined(SQLITE_MUTEX_OMIT) */
/************** End of mutex_noop.c ******************************************/
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 17716 17717 17718 17719 17720 17721 17722 17723 17724 17725 17726 17727 17728 17729 |
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
return sqlite3NoopMutex();
}
#endif /* defined(SQLITE_MUTEX_NOOP) */
#endif /* !defined(SQLITE_MUTEX_OMIT) */
/************** End of mutex_noop.c ******************************************/
/************** Begin file mutex_unix.c **************************************/
/*
** 2007 August 28
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
|
| ︙ | ︙ | |||
18332 18333 18334 18335 18336 18337 18338 | ** mutexIsNT() is only used for the TryEnterCriticalSection() API call, ** which is only available if your application was compiled with ** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef ** this out as well. */ #if 0 | | | 18127 18128 18129 18130 18131 18132 18133 18134 18135 18136 18137 18138 18139 18140 18141 |
** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
** which is only available if your application was compiled with
** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only
** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef
** this out as well.
*/
#if 0
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define mutexIsNT() (1)
#else
static int mutexIsNT(void){
static int osType = 0;
if( osType==0 ){
OSVERSIONINFO sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
| ︙ | ︙ | |||
18385 18386 18387 18388 18389 18390 18391 18392 18393 18394 18395 18396 18397 18398 18399 18400 18401 18402 |
/* As winMutexInit() and winMutexEnd() are called as part
** of the sqlite3_initialize and sqlite3_shutdown()
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
int i;
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
}
winMutex_isInit = 1;
}else{
/* Someone else is in the process of initing the static mutexes */
while( !winMutex_isInit ){
| > > > > > > | | 18180 18181 18182 18183 18184 18185 18186 18187 18188 18189 18190 18191 18192 18193 18194 18195 18196 18197 18198 18199 18200 18201 18202 18203 18204 18205 18206 18207 18208 18209 18210 18211 |
/* As winMutexInit() and winMutexEnd() are called as part
** of the sqlite3_initialize and sqlite3_shutdown()
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;
SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
int i;
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
#if SQLITE_OS_WINRT
InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
#else
InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
#endif
}
winMutex_isInit = 1;
}else{
/* Someone else is in the process of initing the static mutexes */
while( !winMutex_isInit ){
sqlite3_win32_sleep(1);
}
}
return SQLITE_OK;
}
static int winMutexEnd(void){
/* The first to decrement to 0 does actual shutdown
|
| ︙ | ︙ | |||
18470 18471 18472 18473 18474 18475 18476 18477 18478 18479 18480 18481 18482 18483 18484 |
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
#ifdef SQLITE_DEBUG
p->id = iType;
#endif
InitializeCriticalSection(&p->mutex);
}
break;
}
default: {
assert( winMutex_isInit==1 );
assert( iType-2 >= 0 );
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
| > > > > | 18271 18272 18273 18274 18275 18276 18277 18278 18279 18280 18281 18282 18283 18284 18285 18286 18287 18288 18289 |
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
#ifdef SQLITE_DEBUG
p->id = iType;
#endif
#if SQLITE_OS_WINRT
InitializeCriticalSectionEx(&p->mutex, 0, 0);
#else
InitializeCriticalSection(&p->mutex);
#endif
}
break;
}
default: {
assert( winMutex_isInit==1 );
assert( iType-2 >= 0 );
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
|
| ︙ | ︙ | |||
19101 19102 19103 19104 19105 19106 19107 19108 19109 19110 19111 19112 19113 19114 |
if( db ){
if( db->pnBytesFreed ){
*db->pnBytesFreed += sqlite3DbMallocSize(db, p);
return;
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf;
db->lookaside.nOut--;
return;
}
}
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
| > > > > | 18906 18907 18908 18909 18910 18911 18912 18913 18914 18915 18916 18917 18918 18919 18920 18921 18922 18923 |
if( db ){
if( db->pnBytesFreed ){
*db->pnBytesFreed += sqlite3DbMallocSize(db, p);
return;
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
#if SQLITE_DEBUG
/* Trash all content in the buffer being freed */
memset(p, 0xaa, db->lookaside.sz);
#endif
pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf;
db->lookaside.nOut--;
return;
}
}
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
|
| ︙ | ︙ | |||
19514 19515 19516 19517 19518 19519 19520 |
** The counter *cnt is incremented each time. After counter exceeds
** 16 (the number of significant digits in a 64-bit float) '0' is
** always returned.
*/
static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
int digit;
LONGDOUBLE_TYPE d;
| | > | 19323 19324 19325 19326 19327 19328 19329 19330 19331 19332 19333 19334 19335 19336 19337 19338 |
** The counter *cnt is incremented each time. After counter exceeds
** 16 (the number of significant digits in a 64-bit float) '0' is
** always returned.
*/
static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
int digit;
LONGDOUBLE_TYPE d;
if( (*cnt)<=0 ) return '0';
(*cnt)--;
digit = (int)*val;
d = digit;
digit += '0';
*val = (*val - d)*10.0;
return (char)digit;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
| ︙ | ︙ | |||
19818 19819 19820 19821 19822 19823 19824 |
exp = 0;
if( sqlite3IsNaN((double)realvalue) ){
bufpt = "NaN";
length = 3;
break;
}
if( realvalue>0.0 ){
| > | > | | > | 19628 19629 19630 19631 19632 19633 19634 19635 19636 19637 19638 19639 19640 19641 19642 19643 19644 19645 19646 19647 |
exp = 0;
if( sqlite3IsNaN((double)realvalue) ){
bufpt = "NaN";
length = 3;
break;
}
if( realvalue>0.0 ){
LONGDOUBLE_TYPE scale = 1.0;
while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
realvalue /= scale;
while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
if( exp>350 ){
if( prefix=='-' ){
bufpt = "-Inf";
}else if( prefix=='+' ){
bufpt = "+Inf";
|
| ︙ | ︙ | |||
19853 19854 19855 19856 19857 19858 19859 |
if( exp<-4 || exp>precision ){
xtype = etEXP;
}else{
precision = precision - exp;
xtype = etFLOAT;
}
}else{
| | | | 19666 19667 19668 19669 19670 19671 19672 19673 19674 19675 19676 19677 19678 19679 19680 19681 19682 19683 19684 19685 19686 19687 19688 19689 19690 19691 19692 19693 19694 19695 |
if( exp<-4 || exp>precision ){
xtype = etEXP;
}else{
precision = precision - exp;
xtype = etFLOAT;
}
}else{
flag_rtz = flag_altform2;
}
if( xtype==etEXP ){
e2 = 0;
}else{
e2 = exp;
}
if( e2+precision+width > etBUFSIZE - 15 ){
bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
if( bufpt==0 ){
pAccum->mallocFailed = 1;
return;
}
}
zOut = bufpt;
nsd = 16 + flag_altform2*10;
flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
/* The sign in front of the number */
if( prefix ){
*(bufpt++) = prefix;
}
/* Digits prior to the decimal point */
if( e2<0 ){
|
| ︙ | ︙ | |||
21441 21442 21443 21444 21445 21446 21447 |
/* adjust the sign of significand */
s = sign<0 ? -s : s;
/* if exponent, scale significand as appropriate
** and store in result. */
if( e ){
| | | 21254 21255 21256 21257 21258 21259 21260 21261 21262 21263 21264 21265 21266 21267 21268 |
/* adjust the sign of significand */
s = sign<0 ? -s : s;
/* if exponent, scale significand as appropriate
** and store in result. */
if( e ){
LONGDOUBLE_TYPE scale = 1.0;
/* attempt to handle extremely small/large numbers better */
if( e>307 && e<342 ){
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
}else{
|
| ︙ | ︙ | |||
22696 22697 22698 22699 22700 22701 22702 |
/* 150 */ "Explain",
};
return azName[i];
}
#endif
/************** End of opcodes.c *********************************************/
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 22509 22510 22511 22512 22513 22514 22515 22516 22517 22518 22519 22520 22521 22522 |
/* 150 */ "Explain",
};
return azName[i];
}
#endif
/************** End of opcodes.c *********************************************/
/************** Begin file os_unix.c *****************************************/
/*
** 2004 May 22
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
|
| ︙ | ︙ | |||
25059 25060 25061 25062 25063 25064 25065 | #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ #endif | | | 22738 22739 22740 22741 22742 22743 22744 22745 22746 22747 22748 22749 22750 22751 22752 | #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ #endif #ifdef SQLITE_DEBUG /* The next group of variables are used to track whether or not the ** transaction counter in bytes 24-27 of database files are updated ** whenever any part of the database changes. An assertion fault will ** occur if a file is updated without also updating the transaction ** counter. This test is made to avoid new problems similar to the ** one described by ticket #3584. */ |
| ︙ | ︙ | |||
25094 25095 25096 25097 25098 25099 25100 | #else # define UNIXFILE_DIRSYNC 0x00 #endif #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ | < | 22773 22774 22775 22776 22777 22778 22779 22780 22781 22782 22783 22784 22785 22786 | #else # define UNIXFILE_DIRSYNC 0x00 #endif #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of os_unix.c ***************/ /************** Begin file os_common.h ***************************************/ /* |
| ︙ | ︙ | |||
25347 25348 25349 25350 25351 25352 25353 25354 25355 25356 25357 25358 25359 25360 |
**
** The safest way to deal with the problem is to always use this wrapper
** which always has the same well-defined interface.
*/
static int posixOpen(const char *zFile, int flags, int mode){
return open(zFile, flags, mode);
}
/* Forward reference */
static int openDirectory(const char*, int*);
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
| > > > > > > > > > | 23025 23026 23027 23028 23029 23030 23031 23032 23033 23034 23035 23036 23037 23038 23039 23040 23041 23042 23043 23044 23045 23046 23047 |
**
** The safest way to deal with the problem is to always use this wrapper
** which always has the same well-defined interface.
*/
static int posixOpen(const char *zFile, int flags, int mode){
return open(zFile, flags, mode);
}
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int posixFchown(int fd, uid_t uid, gid_t gid){
return geteuid() ? 0 : fchown(fd,uid,gid);
}
/* Forward reference */
static int openDirectory(const char*, int*);
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
|
| ︙ | ︙ | |||
25459 25460 25461 25462 25463 25464 25465 |
{ "mkdir", (sqlite3_syscall_ptr)mkdir, 0 },
#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
| | | 23146 23147 23148 23149 23150 23151 23152 23153 23154 23155 23156 23157 23158 23159 23160 |
{ "mkdir", (sqlite3_syscall_ptr)mkdir, 0 },
#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
{ "umask", (sqlite3_syscall_ptr)umask, 0 },
#define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
}; /* End of the overrideable system calls */
|
| ︙ | ︙ | |||
26603 26604 26605 26606 26607 26608 26609 |
if( rc!=SQLITE_BUSY ){
pFile->lastErrno = tErrno;
}
}
}
| | | 24290 24291 24292 24293 24294 24295 24296 24297 24298 24299 24300 24301 24302 24303 24304 |
if( rc!=SQLITE_BUSY ){
pFile->lastErrno = tErrno;
}
}
}
#ifdef SQLITE_DEBUG
/* Set up the transaction-counter change checking flags when
** transitioning from a SHARED to a RESERVED lock. The change
** from SHARED to RESERVED marks the beginning of a normal
** write operation (not a hot journal rollback).
*/
if( rc==SQLITE_OK
&& pFile->eFileLock<=SHARED_LOCK
|
| ︙ | ︙ | |||
26682 26683 26684 26685 26686 26687 26688 |
}
unixEnterMutex();
pInode = pFile->pInode;
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
| | | 24369 24370 24371 24372 24373 24374 24375 24376 24377 24378 24379 24380 24381 24382 24383 |
}
unixEnterMutex();
pInode = pFile->pInode;
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
#ifdef SQLITE_DEBUG
/* When reducing a lock such that other processes can start
** reading the database file again, make sure that the
** transaction counter was updated if any part of the database
** file changed. If the transaction counter is not updated,
** other connections to the same file might not realize that
** the file has changed and hence might not know to flush their
** cache. The use of a stale cache can lead to database corruption.
|
| ︙ | ︙ | |||
27881 27882 27883 27884 27885 27886 27887 |
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
SimulateIOErrorBenign(1);
SimulateIOError( h=(-1) )
SimulateIOErrorBenign(0);
| | | 25568 25569 25570 25571 25572 25573 25574 25575 25576 25577 25578 25579 25580 25581 25582 |
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
SimulateIOErrorBenign(1);
SimulateIOError( h=(-1) )
SimulateIOErrorBenign(0);
#ifdef SQLITE_DEBUG
/* When reducing a lock such that other processes can start
** reading the database file again, make sure that the
** transaction counter was updated if any part of the database
** file changed. If the transaction counter is not updated,
** other connections to the same file might not realize that
** the file has changed and hence might not know to flush their
** cache. The use of a stale cache can lead to database corruption.
|
| ︙ | ︙ | |||
28185 28186 28187 28188 28189 28190 28191 |
#if 0
assert( pFile->pUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
#endif
| | | 25872 25873 25874 25875 25876 25877 25878 25879 25880 25881 25882 25883 25884 25885 25886 |
#if 0
assert( pFile->pUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
#endif
#ifdef SQLITE_DEBUG
/* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a
** normal database file) then record the fact that the database
** has changed. If the transaction counter is modified, record that
** fact too.
*/
if( pFile->inNormalWrite ){
|
| ︙ | ︙ | |||
28476 28477 28478 28479 28480 28481 28482 |
}
rc = robust_ftruncate(pFile->h, (off_t)nByte);
if( rc ){
pFile->lastErrno = errno;
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}else{
| | | 26163 26164 26165 26166 26167 26168 26169 26170 26171 26172 26173 26174 26175 26176 26177 |
}
rc = robust_ftruncate(pFile->h, (off_t)nByte);
if( rc ){
pFile->lastErrno = errno;
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}else{
#ifdef SQLITE_DEBUG
/* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a
** normal database file) and we truncate the file to zero length,
** that effectively updates the change counter. This might happen
** when restoring a database using the backup API from a zero-length
** source.
*/
|
| ︙ | ︙ | |||
28633 28634 28635 28636 28637 28638 28639 |
unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
| | | 26320 26321 26322 26323 26324 26325 26326 26327 26328 26329 26330 26331 26332 26333 26334 |
unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
#ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and
** it hence it is OK for the transaction change counter to be
** unchanged.
*/
case SQLITE_FCNTL_DB_UNCHANGED: {
((unixFile*)id)->dbUpdate = 0;
|
| ︙ | ︙ | |||
28984 28985 28986 28987 28988 28989 28990 |
if( pShmNode->h<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
goto shm_open_err;
}
/* If this process is running as root, make sure that the SHM file
** is owned by the same user that owns the original database. Otherwise,
| | < < < | < < | 26671 26672 26673 26674 26675 26676 26677 26678 26679 26680 26681 26682 26683 26684 26685 26686 26687 |
if( pShmNode->h<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
goto shm_open_err;
}
/* If this process is running as root, make sure that the SHM file
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
/* Check to see if another process is holding the dead-man switch.
** If not, truncate the file to zero length.
*/
rc = SQLITE_OK;
if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
if( robust_ftruncate(pShmNode->h, 0) ){
|
| ︙ | ︙ | |||
30197 30198 30199 30200 30201 30202 30203 |
if( fd<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
goto open_finished;
}
/* If this process is running as root and if creating a new rollback
** journal or WAL file, set the ownership of the journal or WAL to be
| | < < < | | 27879 27880 27881 27882 27883 27884 27885 27886 27887 27888 27889 27890 27891 27892 27893 27894 27895 27896 |
if( fd<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
goto open_finished;
}
/* If this process is running as root and if creating a new rollback
** journal or WAL file, set the ownership of the journal or WAL to be
** the same as the original database.
*/
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
osFchown(fd, uid, gid);
}
}
assert( fd>=0 );
if( pOutFlags ){
*pOutFlags = flags;
}
|
| ︙ | ︙ | |||
32164 32165 32166 32167 32168 32169 32170 32171 32172 32173 32174 32175 32176 32177 32178 32179 32180 32181 32182 32183 | #endif #endif /* !defined(_OS_COMMON_H_) */ /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_win.c *********************/ /* ** Some Microsoft compilers lack this definition. */ #ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif /* Forward references */ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ /* ** WinCE lacks native support for file locking so we have to fake it | > > > > > > > > > > > > > > > | 29843 29844 29845 29846 29847 29848 29849 29850 29851 29852 29853 29854 29855 29856 29857 29858 29859 29860 29861 29862 29863 29864 29865 29866 29867 29868 29869 29870 29871 29872 29873 29874 29875 29876 29877 | #endif #endif /* !defined(_OS_COMMON_H_) */ /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_win.c *********************/ /* ** Macro to find the minimum of two numeric values. */ #ifndef MIN # define MIN(x,y) ((x)<(y)?(x):(y)) #endif /* ** Some Microsoft compilers lack this definition. */ #ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif #ifndef FILE_FLAG_MASK # define FILE_FLAG_MASK (0xFF3C0000) #endif #ifndef FILE_ATTRIBUTE_MASK # define FILE_ATTRIBUTE_MASK (0x0003FFF7) #endif /* Forward references */ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ /* ** WinCE lacks native support for file locking so we have to fake it |
| ︙ | ︙ | |||
32219 32220 32221 32222 32223 32224 32225 32226 32227 32228 32229 32230 32231 32232 32233 32234 32235 32236 32237 |
/*
** Allowed values for winFile.ctrlFlags
*/
#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
/*
* If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
* various Win32 API heap functions instead of our own.
*/
#ifdef SQLITE_WIN32_MALLOC
/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
#endif
| > > > > > > > > > > > > > > > > > > > > > > > > > > | 29913 29914 29915 29916 29917 29918 29919 29920 29921 29922 29923 29924 29925 29926 29927 29928 29929 29930 29931 29932 29933 29934 29935 29936 29937 29938 29939 29940 29941 29942 29943 29944 29945 29946 29947 29948 29949 29950 29951 29952 29953 29954 29955 29956 29957 |
/*
** Allowed values for winFile.ctrlFlags
*/
#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
/*
* The size of the buffer used by sqlite3_win32_write_debug().
*/
#ifndef SQLITE_WIN32_DBG_BUF_SIZE
# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD)))
#endif
/*
* If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
* various Win32 API heap functions instead of our own.
*/
#ifdef SQLITE_WIN32_MALLOC
/*
* If this is non-zero, an isolated heap will be created by the native Win32
* allocator subsystem; otherwise, the default process heap will be used. This
* setting has no effect when compiling for WinRT. By default, this is enabled
* and an isolated heap will be created to store all allocated data.
*
******************************************************************************
* WARNING: It is important to note that when this setting is non-zero and the
* winMemShutdown function is called (e.g. by the sqlite3_shutdown
* function), all data that was allocated using the isolated heap will
* be freed immediately and any attempt to access any of that freed
* data will almost certainly result in an immediate access violation.
******************************************************************************
*/
#ifndef SQLITE_WIN32_HEAP_CREATE
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
#endif
/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
#endif
|
| ︙ | ︙ | |||
32308 32309 32310 32311 32312 32313 32314 | */ #ifdef SQLITE_TEST SQLITE_API int sqlite3_os_type = 0; #else static int sqlite3_os_type = 0; #endif | < < < < < < | | < | < > | < < > > > | | | < < < < < < < | < < > > > > | 30028 30029 30030 30031 30032 30033 30034 30035 30036 30037 30038 30039 30040 30041 30042 30043 30044 30045 30046 30047 30048 30049 30050 30051 30052 30053 30054 30055 30056 30057 30058 30059 30060 30061 30062 30063 30064 30065 30066 30067 30068 30069 30070 30071 30072 30073 30074 30075 30076 30077 30078 30079 30080 30081 |
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite3_os_type = 0;
#else
static int sqlite3_os_type = 0;
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_ANSI
#endif
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_WIDE
#endif
#ifndef SYSCALL
# define SYSCALL sqlite3_syscall_ptr
#endif
/*
** This function is not available on Windows CE or WinRT.
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define osAreFileApisANSI() 1
#endif
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
** testing and sandboxing. The following array holds the names and pointers
** to all overrideable system calls.
*/
static struct win_syscall {
const char *zName; /* Name of the sytem call */
sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
sqlite3_syscall_ptr pDefault; /* Default value */
} aSyscall[] = {
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 },
#else
{ "AreFileApisANSI", (SYSCALL)0, 0 },
#endif
#ifndef osAreFileApisANSI
#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
#endif
#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
{ "CharLowerW", (SYSCALL)CharLowerW, 0 },
#else
{ "CharLowerW", (SYSCALL)0, 0 },
#endif
|
| ︙ | ︙ | |||
32389 32390 32391 32392 32393 32394 32395 |
#else
{ "CreateFileA", (SYSCALL)0, 0 },
#endif
#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
| | < < < < < | | | | | | | | | | | | | | | | | | | | > > > > | | | | | | > > > > | | | | | | > > > > | | | > > > > | > > > > | | | | > > > > | | | | > > > > | | < < < > > > > > < < < > > > > > > > > > | | | | | > > > > | > > > > | | | < < < > > > > > < < < > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 30098 30099 30100 30101 30102 30103 30104 30105 30106 30107 30108 30109 30110 30111 30112 30113 30114 30115 30116 30117 30118 30119 30120 30121 30122 30123 30124 30125 30126 30127 30128 30129 30130 30131 30132 30133 30134 30135 30136 30137 30138 30139 30140 30141 30142 30143 30144 30145 30146 30147 30148 30149 30150 30151 30152 30153 30154 30155 30156 30157 30158 30159 30160 30161 30162 30163 30164 30165 30166 30167 30168 30169 30170 30171 30172 30173 30174 30175 30176 30177 30178 30179 30180 30181 30182 30183 30184 30185 30186 30187 30188 30189 30190 30191 30192 30193 30194 30195 30196 30197 30198 30199 30200 30201 30202 30203 30204 30205 30206 30207 30208 30209 30210 30211 30212 30213 30214 30215 30216 30217 30218 30219 30220 30221 30222 30223 30224 30225 30226 30227 30228 30229 30230 30231 30232 30233 30234 30235 30236 30237 30238 30239 30240 30241 30242 30243 30244 30245 30246 30247 30248 30249 30250 30251 30252 30253 30254 30255 30256 30257 30258 30259 30260 30261 30262 30263 30264 30265 30266 30267 30268 30269 30270 30271 30272 30273 30274 30275 30276 30277 30278 30279 30280 30281 30282 30283 30284 30285 30286 30287 30288 30289 30290 30291 30292 30293 30294 30295 30296 30297 30298 30299 30300 30301 30302 30303 30304 30305 30306 30307 30308 30309 30310 30311 30312 30313 30314 30315 30316 30317 30318 30319 30320 30321 30322 30323 30324 30325 30326 30327 30328 30329 30330 30331 30332 30333 30334 30335 30336 30337 30338 30339 30340 30341 30342 30343 30344 30345 30346 30347 30348 30349 30350 30351 30352 30353 30354 30355 30356 30357 30358 30359 30360 30361 30362 30363 30364 30365 30366 30367 30368 30369 30370 30371 30372 30373 30374 30375 30376 30377 30378 30379 30380 30381 30382 30383 30384 30385 30386 30387 30388 30389 30390 30391 30392 30393 30394 30395 30396 30397 30398 30399 30400 30401 30402 30403 30404 30405 30406 30407 30408 30409 30410 30411 30412 30413 30414 30415 30416 30417 30418 30419 30420 30421 30422 30423 30424 30425 30426 30427 30428 30429 30430 30431 30432 30433 30434 30435 30436 30437 30438 30439 30440 30441 30442 30443 30444 30445 30446 30447 30448 30449 30450 30451 30452 30453 30454 30455 30456 30457 30458 30459 30460 30461 30462 30463 30464 30465 30466 30467 30468 30469 30470 30471 30472 30473 30474 30475 30476 30477 30478 30479 30480 30481 30482 30483 30484 30485 30486 30487 30488 30489 30490 30491 30492 30493 30494 30495 30496 30497 30498 30499 30500 30501 30502 30503 30504 30505 30506 30507 30508 30509 30510 30511 30512 30513 30514 30515 30516 30517 30518 30519 30520 30521 30522 30523 30524 30525 30526 30527 30528 30529 30530 30531 30532 30533 30534 30535 30536 30537 30538 30539 30540 30541 30542 30543 30544 30545 30546 30547 30548 30549 30550 30551 30552 30553 30554 30555 30556 30557 30558 30559 30560 30561 30562 30563 30564 30565 30566 30567 30568 30569 30570 30571 30572 30573 30574 30575 30576 30577 30578 30579 30580 30581 30582 30583 30584 30585 30586 30587 30588 30589 30590 30591 30592 30593 30594 30595 30596 30597 30598 30599 30600 30601 30602 30603 30604 30605 30606 30607 30608 30609 30610 30611 30612 30613 30614 30615 30616 30617 30618 30619 30620 30621 30622 30623 30624 30625 30626 30627 30628 30629 30630 30631 30632 30633 |
#else
{ "CreateFileA", (SYSCALL)0, 0 },
#endif
#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateFileW", (SYSCALL)CreateFileW, 0 },
#else
{ "CreateFileW", (SYSCALL)0, 0 },
#endif
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
#else
{ "CreateFileMappingW", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
DWORD,DWORD,DWORD,LPCWSTR))aSyscall[6].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateMutexW", (SYSCALL)CreateMutexW, 0 },
#else
{ "CreateMutexW", (SYSCALL)0, 0 },
#endif
#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
LPCWSTR))aSyscall[7].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "DeleteFileA", (SYSCALL)DeleteFileA, 0 },
#else
{ "DeleteFileA", (SYSCALL)0, 0 },
#endif
#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[8].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "DeleteFileW", (SYSCALL)DeleteFileW, 0 },
#else
{ "DeleteFileW", (SYSCALL)0, 0 },
#endif
#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
#else
{ "FileTimeToLocalFileTime", (SYSCALL)0, 0 },
#endif
#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPFILETIME))aSyscall[10].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 },
#else
{ "FileTimeToSystemTime", (SYSCALL)0, 0 },
#endif
#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPSYSTEMTIME))aSyscall[11].pCurrent)
{ "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 },
#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[12].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "FormatMessageA", (SYSCALL)FormatMessageA, 0 },
#else
{ "FormatMessageA", (SYSCALL)0, 0 },
#endif
#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
DWORD,va_list*))aSyscall[13].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "FormatMessageW", (SYSCALL)FormatMessageW, 0 },
#else
{ "FormatMessageW", (SYSCALL)0, 0 },
#endif
#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
DWORD,va_list*))aSyscall[14].pCurrent)
{ "FreeLibrary", (SYSCALL)FreeLibrary, 0 },
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[15].pCurrent)
{ "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 },
#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[16].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 },
#else
{ "GetDiskFreeSpaceA", (SYSCALL)0, 0 },
#endif
#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[17].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 },
#else
{ "GetDiskFreeSpaceW", (SYSCALL)0, 0 },
#endif
#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[18].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 },
#else
{ "GetFileAttributesA", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[19].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 },
#else
{ "GetFileAttributesW", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[20].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 },
#else
{ "GetFileAttributesExW", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
LPVOID))aSyscall[21].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetFileSize", (SYSCALL)GetFileSize, 0 },
#else
{ "GetFileSize", (SYSCALL)0, 0 },
#endif
#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[22].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 },
#else
{ "GetFullPathNameA", (SYSCALL)0, 0 },
#endif
#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
LPSTR*))aSyscall[23].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 },
#else
{ "GetFullPathNameW", (SYSCALL)0, 0 },
#endif
#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
LPWSTR*))aSyscall[24].pCurrent)
{ "GetLastError", (SYSCALL)GetLastError, 0 },
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[25].pCurrent)
#if SQLITE_OS_WINCE
/* The GetProcAddressA() routine is only available on Windows CE. */
{ "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 },
#else
/* All other Windows platforms expect GetProcAddress() to take
** an ANSI string regardless of the _UNICODE setting */
{ "GetProcAddressA", (SYSCALL)GetProcAddress, 0 },
#endif
#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
LPCSTR))aSyscall[26].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 },
#else
{ "GetSystemInfo", (SYSCALL)0, 0 },
#endif
#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[27].pCurrent)
{ "GetSystemTime", (SYSCALL)GetSystemTime, 0 },
#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[28].pCurrent)
#if !SQLITE_OS_WINCE
{ "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
#else
{ "GetSystemTimeAsFileTime", (SYSCALL)0, 0 },
#endif
#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
LPFILETIME))aSyscall[29].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetTempPathA", (SYSCALL)GetTempPathA, 0 },
#else
{ "GetTempPathA", (SYSCALL)0, 0 },
#endif
#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[30].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetTempPathW", (SYSCALL)GetTempPathW, 0 },
#else
{ "GetTempPathW", (SYSCALL)0, 0 },
#endif
#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[31].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetTickCount", (SYSCALL)GetTickCount, 0 },
#else
{ "GetTickCount", (SYSCALL)0, 0 },
#endif
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[32].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
#else
{ "GetVersionExA", (SYSCALL)0, 0 },
#endif
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[33].pCurrent)
{ "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
SIZE_T))aSyscall[34].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapCreate", (SYSCALL)HeapCreate, 0 },
#else
{ "HeapCreate", (SYSCALL)0, 0 },
#endif
#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
SIZE_T))aSyscall[35].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
#else
{ "HeapDestroy", (SYSCALL)0, 0 },
#endif
#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent)
{ "HeapFree", (SYSCALL)HeapFree, 0 },
#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[37].pCurrent)
{ "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
SIZE_T))aSyscall[38].pCurrent)
{ "HeapSize", (SYSCALL)HeapSize, 0 },
#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[39].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapValidate", (SYSCALL)HeapValidate, 0 },
#else
{ "HeapValidate", (SYSCALL)0, 0 },
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[40].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
#else
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[41].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
#else
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[42].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
#else
{ "LocalFree", (SYSCALL)0, 0 },
#endif
#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[43].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
#else
{ "LockFile", (SYSCALL)0, 0 },
#endif
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[44].pCurrent)
#endif
#if !SQLITE_OS_WINCE
{ "LockFileEx", (SYSCALL)LockFileEx, 0 },
#else
{ "LockFileEx", (SYSCALL)0, 0 },
#endif
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[45].pCurrent)
#endif
#if !SQLITE_OS_WINRT
{ "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
#else
{ "MapViewOfFile", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
SIZE_T))aSyscall[46].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
int))aSyscall[47].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
LARGE_INTEGER*))aSyscall[48].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[49].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[50].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
#else
{ "SetFilePointer", (SYSCALL)0, 0 },
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
DWORD))aSyscall[51].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
#else
{ "Sleep", (SYSCALL)0, 0 },
#endif
#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[52].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
LPFILETIME))aSyscall[53].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
#else
{ "UnlockFile", (SYSCALL)0, 0 },
#endif
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[54].pCurrent)
#endif
#if !SQLITE_OS_WINCE
{ "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 },
#else
{ "UnlockFileEx", (SYSCALL)0, 0 },
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[55].pCurrent)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
LPCSTR,LPBOOL))aSyscall[57].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[58].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
#else
{ "CreateEventExW", (SYSCALL)0, 0 },
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
DWORD,DWORD))aSyscall[59].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
#else
{ "WaitForSingleObject", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[60].pCurrent)
#if !SQLITE_OS_WINCE
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#else
{ "WaitForSingleObjectEx", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[61].pCurrent)
#if !SQLITE_OS_WINCE
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
#else
{ "SetFilePointerEx", (SYSCALL)0, 0 },
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
PLARGE_INTEGER,DWORD))aSyscall[62].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
#else
{ "GetFileInformationByHandleEx", (SYSCALL)0, 0 },
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
#else
{ "MapViewOfFileFromApp", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
SIZE_T))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
#else
{ "CreateFile2", (SYSCALL)0, 0 },
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
#else
{ "LoadPackagedLibrary", (SYSCALL)0, 0 },
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
DWORD))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
#else
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
#else
{ "GetNativeSystemInfo", (SYSCALL)0, 0 },
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
LPSYSTEM_INFO))aSyscall[68].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
#else
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[69].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
#else
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[70].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
{ "CreateFileMappingFromApp", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[72].pCurrent)
}; /* End of the overrideable system calls */
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "win32" VFSes. Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
|
| ︙ | ︙ | |||
32837 32838 32839 32840 32841 32842 32843 32844 32845 32846 32847 32848 32849 32850 32851 32852 32853 32854 32855 |
}
}
for(i++; i<ArraySize(aSyscall); i++){
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation: Win95, Win98, and WinME lack
** the LockFileEx() API. But we can still statically link against that
** API as long as we don't call it when running Win95/98/ME. A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 30705 30706 30707 30708 30709 30710 30711 30712 30713 30714 30715 30716 30717 30718 30719 30720 30721 30722 30723 30724 30725 30726 30727 30728 30729 30730 30731 30732 30733 30734 30735 30736 30737 30738 30739 30740 30741 30742 30743 30744 30745 30746 30747 30748 30749 30750 30751 30752 30753 30754 30755 30756 30757 30758 30759 30760 30761 30762 30763 30764 30765 30766 30767 30768 30769 30770 30771 30772 30773 30774 30775 30776 30777 30778 30779 30780 30781 30782 30783 30784 30785 30786 30787 30788 30789 |
}
}
for(i++; i<ArraySize(aSyscall); i++){
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
*/
SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){
char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
#if defined(SQLITE_WIN32_HAS_ANSI)
if( nMin>0 ){
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
memcpy(zDbgBuf, zBuf, nMin);
osOutputDebugStringA(zDbgBuf);
}else{
osOutputDebugStringA(zBuf);
}
#elif defined(SQLITE_WIN32_HAS_WIDE)
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
if ( osMultiByteToWideChar(
osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
return;
}
osOutputDebugStringW((LPCWSTR)zDbgBuf);
#else
if( nMin>0 ){
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
memcpy(zDbgBuf, zBuf, nMin);
fprintf(stderr, "%s", zDbgBuf);
}else{
fprintf(stderr, "%s", zBuf);
}
#endif
}
/*
** The following routine suspends the current thread for at least ms
** milliseconds. This is equivalent to the Win32 Sleep() interface.
*/
#if SQLITE_OS_WINRT
static HANDLE sleepObj = NULL;
#endif
SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
#if SQLITE_OS_WINRT
if ( sleepObj==NULL ){
sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
SYNCHRONIZE);
}
assert( sleepObj!=NULL );
osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
#else
osSleep(milliseconds);
#endif
}
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation: Win95, Win98, and WinME lack
** the LockFileEx() API. But we can still statically link against that
** API as long as we don't call it when running Win95/98/ME. A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define isNT() (1)
#else
static int isNT(void){
if( sqlite3_os_type==0 ){
OSVERSIONINFOA sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
osGetVersionExA(&sInfo);
|
| ︙ | ︙ | |||
32875 32876 32877 32878 32879 32880 32881 | HANDLE hHeap; void *p; winMemAssertMagic(); hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); | | | 30801 30802 30803 30804 30805 30806 30807 30808 30809 30810 30811 30812 30813 30814 30815 |
HANDLE hHeap;
void *p;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
assert( nBytes>=0 );
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
if( !p ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
nBytes, osGetLastError(), (void*)hHeap);
|
| ︙ | ︙ | |||
32897 32898 32899 32900 32901 32902 32903 |
static void winMemFree(void *pPrior){
HANDLE hHeap;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
| | | | 30823 30824 30825 30826 30827 30828 30829 30830 30831 30832 30833 30834 30835 30836 30837 30838 30839 30840 30841 30842 30843 30844 30845 30846 30847 30848 30849 30850 30851 30852 30853 30854 30855 30856 30857 30858 |
static void winMemFree(void *pPrior){
HANDLE hHeap;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
pPrior, osGetLastError(), (void*)hHeap);
}
}
/*
** Change the size of an existing memory allocation
*/
static void *winMemRealloc(void *pPrior, int nBytes){
HANDLE hHeap;
void *p;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
assert( nBytes>=0 );
if( !pPrior ){
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
}else{
p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
|
| ︙ | ︙ | |||
32946 32947 32948 32949 32950 32951 32952 | HANDLE hHeap; SIZE_T n; winMemAssertMagic(); hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); | | | 30872 30873 30874 30875 30876 30877 30878 30879 30880 30881 30882 30883 30884 30885 30886 |
HANDLE hHeap;
SIZE_T n;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
if( !p ) return 0;
n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
if( n==(SIZE_T)-1 ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
p, osGetLastError(), (void*)hHeap);
|
| ︙ | ︙ | |||
32974 32975 32976 32977 32978 32979 32980 32981 32982 32983 32984 32985 32986 32987 32988 32989 32990 32991 32992 32993 32994 32995 |
** Initialize this module.
*/
static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
assert( pWinMemData->magic==WINMEM_MAGIC );
if( !pWinMemData->hHeap ){
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE,
SQLITE_WIN32_HEAP_MAX_SIZE);
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
}
assert( pWinMemData->hHeap!=0 );
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
| > > > > > > > > > > > > > | | | 30900 30901 30902 30903 30904 30905 30906 30907 30908 30909 30910 30911 30912 30913 30914 30915 30916 30917 30918 30919 30920 30921 30922 30923 30924 30925 30926 30927 30928 30929 30930 30931 30932 30933 30934 30935 30936 30937 30938 30939 30940 30941 30942 30943 30944 30945 30946 30947 30948 30949 30950 30951 30952 30953 30954 30955 30956 30957 |
** Initialize this module.
*/
static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
assert( pWinMemData->magic==WINMEM_MAGIC );
#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
if( !pWinMemData->hHeap ){
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE,
SQLITE_WIN32_HEAP_MAX_SIZE);
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
assert( pWinMemData->bOwned );
}
#else
pWinMemData->hHeap = osGetProcessHeap();
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to GetProcessHeap (%d)", osGetLastError());
return SQLITE_NOMEM;
}
pWinMemData->bOwned = FALSE;
assert( !pWinMemData->bOwned );
#endif
assert( pWinMemData->hHeap!=0 );
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
return SQLITE_OK;
}
/*
** Deinitialize this module.
*/
static void winMemShutdown(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return;
if( pWinMemData->hHeap ){
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
if( pWinMemData->bOwned ){
if( !osHeapDestroy(pWinMemData->hHeap) ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
osGetLastError(), (void*)pWinMemData->hHeap);
}
|
| ︙ | ︙ | |||
33204 33205 33206 33207 33208 33209 33210 33211 33212 33213 33214 33215 33216 33217 33218 33219 33220 33221 33222 33223 33224 33225 33226 33227 33228 |
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
*/
DWORD dwLen = 0;
char *zOut = 0;
if( isNT() ){
LPWSTR zTempWide = NULL;
dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
(LPWSTR) &zTempWide,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
zOut = unicodeToUtf8(zTempWide);
sqlite3EndBenignMalloc();
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTempWide);
}
| > > > > > > > > > > > > > > < < < < > | | < > | 31143 31144 31145 31146 31147 31148 31149 31150 31151 31152 31153 31154 31155 31156 31157 31158 31159 31160 31161 31162 31163 31164 31165 31166 31167 31168 31169 31170 31171 31172 31173 31174 31175 31176 31177 31178 31179 31180 31181 31182 31183 31184 31185 31186 31187 31188 31189 31190 31191 31192 31193 31194 31195 31196 31197 31198 31199 31200 31201 31202 31203 31204 31205 31206 31207 31208 31209 31210 31211 |
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
*/
DWORD dwLen = 0;
char *zOut = 0;
if( isNT() ){
#if SQLITE_OS_WINRT
WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
zTempWide,
MAX_PATH,
0);
#else
LPWSTR zTempWide = NULL;
dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
(LPWSTR) &zTempWide,
0,
0);
#endif
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
zOut = unicodeToUtf8(zTempWide);
sqlite3EndBenignMalloc();
#if !SQLITE_OS_WINRT
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTempWide);
#endif
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zTemp = NULL;
dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
(LPSTR) &zTemp,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
sqlite3EndBenignMalloc();
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTemp);
}
}
#endif
if( 0 == dwLen ){
sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno);
}else{
/* copy a maximum of nBuf chars to output buffer */
sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
/* free the UTF8 buffer */
sqlite3_free(zOut);
|
| ︙ | ︙ | |||
33330 33331 33332 33333 33334 33335 33336 |
*pError = e;
}
return 0;
}
if( e==ERROR_ACCESS_DENIED ||
e==ERROR_LOCK_VIOLATION ||
e==ERROR_SHARING_VIOLATION ){
| | | 31280 31281 31282 31283 31284 31285 31286 31287 31288 31289 31290 31291 31292 31293 31294 |
*pError = e;
}
return 0;
}
if( e==ERROR_ACCESS_DENIED ||
e==ERROR_LOCK_VIOLATION ||
e==ERROR_SHARING_VIOLATION ){
sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
++*pnRetry;
return 1;
}
if( pError ){
*pError = e;
}
return 0;
|
| ︙ | ︙ | |||
33391 33392 33393 33394 33395 33396 33397 |
/*
** Acquire a lock on the handle h
*/
static void winceMutexAcquire(HANDLE h){
DWORD dwErr;
do {
| | | 31341 31342 31343 31344 31345 31346 31347 31348 31349 31350 31351 31352 31353 31354 31355 |
/*
** Acquire a lock on the handle h
*/
static void winceMutexAcquire(HANDLE h){
DWORD dwErr;
do {
dwErr = osWaitForSingleObject(h, INFINITE);
} while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
}
/*
** Release a lock acquired by winceMutexAcquire()
*/
#define winceMutexRelease(h) ReleaseMutex(h)
|
| ︙ | ︙ | |||
33522 33523 33524 33525 33526 33527 33528 | } } /* ** An implementation of the LockFile() API of Windows for CE */ static BOOL winceLockFile( | | | 31472 31473 31474 31475 31476 31477 31478 31479 31480 31481 31482 31483 31484 31485 31486 |
}
}
/*
** An implementation of the LockFile() API of Windows for CE
*/
static BOOL winceLockFile(
LPHANDLE phFile,
DWORD dwFileOffsetLow,
DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh
){
winFile *pFile = HANDLE_TO_WINFILE(phFile);
BOOL bReturn = FALSE;
|
| ︙ | ︙ | |||
33586 33587 33588 33589 33590 33591 33592 | return bReturn; } /* ** An implementation of the UnlockFile API of Windows for CE */ static BOOL winceUnlockFile( | | | 31536 31537 31538 31539 31540 31541 31542 31543 31544 31545 31546 31547 31548 31549 31550 |
return bReturn;
}
/*
** An implementation of the UnlockFile API of Windows for CE
*/
static BOOL winceUnlockFile(
LPHANDLE phFile,
DWORD dwFileOffsetLow,
DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow,
DWORD nNumberOfBytesToUnlockHigh
){
winFile *pFile = HANDLE_TO_WINFILE(phFile);
BOOL bReturn = FALSE;
|
| ︙ | ︙ | |||
33643 33644 33645 33646 33647 33648 33649 |
bReturn = TRUE;
}
}
winceMutexRelease(pFile->hMutex);
return bReturn;
}
| < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 31593 31594 31595 31596 31597 31598 31599 31600 31601 31602 31603 31604 31605 31606 31607 31608 31609 31610 31611 31612 31613 31614 31615 31616 31617 31618 31619 31620 31621 31622 31623 31624 31625 31626 31627 31628 31629 31630 31631 31632 31633 31634 31635 31636 31637 31638 31639 31640 31641 31642 31643 31644 31645 31646 31647 31648 31649 31650 31651 31652 31653 31654 31655 31656 31657 31658 31659 31660 31661 31662 31663 31664 31665 31666 31667 31668 31669 31670 31671 31672 31673 31674 31675 31676 31677 31678 31679 31680 31681 31682 31683 31684 31685 31686 31687 31688 31689 31690 31691 31692 31693 |
bReturn = TRUE;
}
}
winceMutexRelease(pFile->hMutex);
return bReturn;
}
/*
** End of the special code for wince
*****************************************************************************/
#endif /* SQLITE_OS_WINCE */
/*
** Lock a file region.
*/
static BOOL winLockFile(
LPHANDLE phFile,
DWORD flags,
DWORD offsetLow,
DWORD offsetHigh,
DWORD numBytesLow,
DWORD numBytesHigh
){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
** API LockFile.
*/
return winceLockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
if( isNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
ovlp.OffsetHigh = offsetHigh;
return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
}else{
return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
}
#endif
}
/*
** Unlock a file region.
*/
static BOOL winUnlockFile(
LPHANDLE phFile,
DWORD offsetLow,
DWORD offsetHigh,
DWORD numBytesLow,
DWORD numBytesHigh
){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
** API UnlockFile.
*/
return winceUnlockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
if( isNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
ovlp.OffsetHigh = offsetHigh;
return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
}else{
return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
}
#endif
}
/*****************************************************************************
** The next group of routines implement the I/O methods specified
** by the sqlite3_io_methods object.
******************************************************************************/
/*
** Some Microsoft compilers lack this definition.
*/
#ifndef INVALID_SET_FILE_POINTER
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
/*
** Move the current position of the file handle passed as the first
** argument to offset iOffset within the file. If successful, return 0.
** Otherwise, set pFile->lastErrno and return non-zero.
*/
static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
#if !SQLITE_OS_WINRT
LONG upperBits; /* Most sig. 32 bits of new offset */
LONG lowerBits; /* Least sig. 32 bits of new offset */
DWORD dwRet; /* Value returned by SetFilePointer() */
DWORD lastErrno; /* Value returned by GetLastError() */
upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
lowerBits = (LONG)(iOffset & 0xffffffff);
|
| ︙ | ︙ | |||
33716 33717 33718 33719 33720 33721 33722 33723 33724 33725 33726 33727 33728 33729 |
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"seekWinFile", pFile->zPath);
return 1;
}
return 0;
}
/*
** Close a file.
**
** It is reported that an attempt to close a handle might sometimes
** fail. This is a very unreasonable result, but Windows is notorious
| > > > > > > > > > > > > > > > > > > > > | 31706 31707 31708 31709 31710 31711 31712 31713 31714 31715 31716 31717 31718 31719 31720 31721 31722 31723 31724 31725 31726 31727 31728 31729 31730 31731 31732 31733 31734 31735 31736 31737 31738 31739 |
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"seekWinFile", pFile->zPath);
return 1;
}
return 0;
#else
/*
** Same as above, except that this implementation works for WinRT.
*/
LARGE_INTEGER x; /* The new offset */
BOOL bRet; /* Value returned by SetFilePointerEx() */
x.QuadPart = iOffset;
bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
if(!bRet){
pFile->lastErrno = osGetLastError();
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"seekWinFile", pFile->zPath);
return 1;
}
return 0;
#endif
}
/*
** Close a file.
**
** It is reported that an attempt to close a handle might sometimes
** fail. This is a very unreasonable result, but Windows is notorious
|
| ︙ | ︙ | |||
33739 33740 33741 33742 33743 33744 33745 |
assert( id!=0 );
assert( pFile->pShm==0 );
OSTRACE(("CLOSE %d\n", pFile->h));
do{
rc = osCloseHandle(pFile->h);
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
| | | | 31749 31750 31751 31752 31753 31754 31755 31756 31757 31758 31759 31760 31761 31762 31763 31764 31765 31766 31767 31768 31769 31770 31771 31772 31773 31774 |
assert( id!=0 );
assert( pFile->pShm==0 );
OSTRACE(("CLOSE %d\n", pFile->h));
do{
rc = osCloseHandle(pFile->h);
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
#if SQLITE_OS_WINCE
#define WINCE_DELETION_ATTEMPTS 3
winceDestroyLock(pFile);
if( pFile->zDeleteOnClose ){
int cnt = 0;
while(
osDeleteFileW(pFile->zDeleteOnClose)==0
&& osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
&& cnt++ < WINCE_DELETION_ATTEMPTS
){
sqlite3_win32_sleep(100); /* Wait a little before trying again */
}
sqlite3_free(pFile->zDeleteOnClose);
}
#endif
OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
if( rc ){
pFile->h = NULL;
|
| ︙ | ︙ | |||
34005 34006 34007 34008 34009 34010 34011 |
#endif
}
/*
** Determine the current size of a file in bytes
*/
static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
| < < < > > > > > > > > > > > > > > > > > > > | > | | < | | | < > > | > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < | > > > | > > > > > > | | > | < > | < < > | | | < > | 32015 32016 32017 32018 32019 32020 32021 32022 32023 32024 32025 32026 32027 32028 32029 32030 32031 32032 32033 32034 32035 32036 32037 32038 32039 32040 32041 32042 32043 32044 32045 32046 32047 32048 32049 32050 32051 32052 32053 32054 32055 32056 32057 32058 32059 32060 32061 32062 32063 32064 32065 32066 32067 32068 32069 32070 32071 32072 32073 32074 32075 32076 32077 32078 32079 32080 32081 32082 32083 32084 32085 32086 32087 32088 32089 32090 32091 32092 32093 32094 32095 32096 32097 32098 32099 32100 32101 32102 32103 32104 32105 32106 32107 32108 32109 32110 32111 32112 32113 32114 32115 32116 32117 32118 32119 32120 32121 32122 32123 32124 32125 32126 32127 32128 32129 32130 32131 32132 32133 32134 32135 32136 32137 32138 32139 32140 32141 32142 32143 32144 |
#endif
}
/*
** Determine the current size of a file in bytes
*/
static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
winFile *pFile = (winFile*)id;
int rc = SQLITE_OK;
assert( id!=0 );
SimulateIOError(return SQLITE_IOERR_FSTAT);
#if SQLITE_OS_WINRT
{
FILE_STANDARD_INFO info;
if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
&info, sizeof(info)) ){
*pSize = info.EndOfFile.QuadPart;
}else{
pFile->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
"winFileSize", pFile->zPath);
}
}
#else
{
DWORD upperBits;
DWORD lowerBits;
DWORD lastErrno;
lowerBits = osGetFileSize(pFile->h, &upperBits);
*pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
if( (lowerBits == INVALID_FILE_SIZE)
&& ((lastErrno = osGetLastError())!=NO_ERROR) ){
pFile->lastErrno = lastErrno;
rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
"winFileSize", pFile->zPath);
}
}
#endif
return rc;
}
/*
** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
*/
#ifndef LOCKFILE_FAIL_IMMEDIATELY
# define LOCKFILE_FAIL_IMMEDIATELY 1
#endif
#ifndef LOCKFILE_EXCLUSIVE_LOCK
# define LOCKFILE_EXCLUSIVE_LOCK 2
#endif
/*
** Historically, SQLite has used both the LockFile and LockFileEx functions.
** When the LockFile function was used, it was always expected to fail
** immediately if the lock could not be obtained. Also, it always expected to
** obtain an exclusive lock. These flags are used with the LockFileEx function
** and reflect those expectations; therefore, they should not be changed.
*/
#ifndef SQLITE_LOCKFILE_FLAGS
# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \
LOCKFILE_EXCLUSIVE_LOCK)
#endif
/*
** Currently, SQLite never calls the LockFileEx function without wanting the
** call to fail immediately if the lock cannot be obtained.
*/
#ifndef SQLITE_LOCKFILEEX_FLAGS
# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
#endif
/*
** Acquire a reader lock.
** Different API routines are called depending on whether or not this
** is Win9x or WinNT.
*/
static int getReadLock(winFile *pFile){
int res;
if( isNT() ){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
** API LockFileEx.
*/
res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
#else
res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
SHARED_SIZE, 0);
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
int lk;
sqlite3_randomness(sizeof(lk), &lk);
pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
}
#endif
if( res == 0 ){
pFile->lastErrno = osGetLastError();
/* No need to log a failure to lock */
}
return res;
}
/*
** Undo a readlock
*/
static int unlockReadLock(winFile *pFile){
int res;
DWORD lastErrno;
if( isNT() ){
res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
}
#endif
if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
"unlockReadLock", pFile->zPath);
}
return res;
}
|
| ︙ | ︙ | |||
34147 34148 34149 34150 34151 34152 34153 |
*/
newLocktype = pFile->locktype;
if( (pFile->locktype==NO_LOCK)
|| ( (locktype==EXCLUSIVE_LOCK)
&& (pFile->locktype==RESERVED_LOCK))
){
int cnt = 3;
| > | | | 32201 32202 32203 32204 32205 32206 32207 32208 32209 32210 32211 32212 32213 32214 32215 32216 32217 32218 32219 32220 32221 32222 32223 32224 |
*/
newLocktype = pFile->locktype;
if( (pFile->locktype==NO_LOCK)
|| ( (locktype==EXCLUSIVE_LOCK)
&& (pFile->locktype==RESERVED_LOCK))
){
int cnt = 3;
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
PENDING_BYTE, 0, 1, 0))==0 ){
/* Try 3 times to get the pending lock. This is needed to work
** around problems caused by indexing and/or anti-virus software on
** Windows systems.
** If you are using this code as a model for alternative VFSes, do not
** copy this retry logic. It is a hack intended for Windows only.
*/
OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
if( cnt ) sqlite3_win32_sleep(1);
}
gotPendingLock = res;
if( !res ){
lastErrno = osGetLastError();
}
}
|
| ︙ | ︙ | |||
34179 34180 34181 34182 34183 34184 34185 |
}
}
/* Acquire a RESERVED lock
*/
if( locktype==RESERVED_LOCK && res ){
assert( pFile->locktype==SHARED_LOCK );
| | > | | | 32234 32235 32236 32237 32238 32239 32240 32241 32242 32243 32244 32245 32246 32247 32248 32249 32250 32251 32252 32253 32254 32255 32256 32257 32258 32259 32260 32261 32262 32263 32264 32265 32266 32267 32268 32269 32270 32271 32272 32273 32274 32275 32276 32277 32278 32279 32280 32281 32282 32283 32284 |
}
}
/* Acquire a RESERVED lock
*/
if( locktype==RESERVED_LOCK && res ){
assert( pFile->locktype==SHARED_LOCK );
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
if( res ){
newLocktype = RESERVED_LOCK;
}else{
lastErrno = osGetLastError();
}
}
/* Acquire a PENDING lock
*/
if( locktype==EXCLUSIVE_LOCK && res ){
newLocktype = PENDING_LOCK;
gotPendingLock = 0;
}
/* Acquire an EXCLUSIVE lock
*/
if( locktype==EXCLUSIVE_LOCK && res ){
assert( pFile->locktype>=SHARED_LOCK );
res = unlockReadLock(pFile);
OSTRACE(("unreadlock = %d\n", res));
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
SHARED_SIZE, 0);
if( res ){
newLocktype = EXCLUSIVE_LOCK;
}else{
lastErrno = osGetLastError();
OSTRACE(("error-code = %d\n", lastErrno));
getReadLock(pFile);
}
}
/* If we are holding a PENDING lock that ought to be released, then
** release it now.
*/
if( gotPendingLock && locktype==SHARED_LOCK ){
winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
}
/* Update the state of the lock has held in the file descriptor then
** return the appropriate result code.
*/
if( res ){
rc = SQLITE_OK;
|
| ︙ | ︙ | |||
34248 34249 34250 34251 34252 34253 34254 |
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( id!=0 );
if( pFile->locktype>=RESERVED_LOCK ){
rc = 1;
OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
}else{
| | | | 32304 32305 32306 32307 32308 32309 32310 32311 32312 32313 32314 32315 32316 32317 32318 32319 32320 |
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( id!=0 );
if( pFile->locktype>=RESERVED_LOCK ){
rc = 1;
OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
}else{
rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
if( rc ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
rc = !rc;
OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
}
*pResOut = rc;
return SQLITE_OK;
}
|
| ︙ | ︙ | |||
34280 34281 34282 34283 34284 34285 34286 |
int rc = SQLITE_OK;
assert( pFile!=0 );
assert( locktype<=SHARED_LOCK );
OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
pFile->locktype, pFile->sharedLockByte));
type = pFile->locktype;
if( type>=EXCLUSIVE_LOCK ){
| | | | | 32336 32337 32338 32339 32340 32341 32342 32343 32344 32345 32346 32347 32348 32349 32350 32351 32352 32353 32354 32355 32356 32357 32358 32359 32360 32361 32362 32363 32364 32365 |
int rc = SQLITE_OK;
assert( pFile!=0 );
assert( locktype<=SHARED_LOCK );
OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
pFile->locktype, pFile->sharedLockByte));
type = pFile->locktype;
if( type>=EXCLUSIVE_LOCK ){
winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
/* This should never happen. We should always be able to
** reacquire the read lock */
rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
"winUnlock", pFile->zPath);
}
}
if( type>=RESERVED_LOCK ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
if( locktype==NO_LOCK && type>=SHARED_LOCK ){
unlockReadLock(pFile);
}
if( type>=PENDING_LOCK ){
winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
}
pFile->locktype = (u8)locktype;
return rc;
}
/*
** If *pArg is inititially negative then this is a query. Set *pArg to
|
| ︙ | ︙ | |||
34533 34534 34535 34536 34537 34538 34539 |
#define _SHM_WRLCK 3
static int winShmSystemLock(
winShmNode *pFile, /* Apply locks to this open shared-memory segment */
int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
int ofst, /* Offset to first byte to be locked/unlocked */
int nByte /* Number of bytes to lock or unlock */
){
| < < < < < < < < < | > > > | | 32589 32590 32591 32592 32593 32594 32595 32596 32597 32598 32599 32600 32601 32602 32603 32604 32605 32606 32607 32608 32609 32610 32611 32612 32613 32614 32615 |
#define _SHM_WRLCK 3
static int winShmSystemLock(
winShmNode *pFile, /* Apply locks to this open shared-memory segment */
int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
int ofst, /* Offset to first byte to be locked/unlocked */
int nByte /* Number of bytes to lock or unlock */
){
int rc = 0; /* Result code form Lock/UnlockFileEx() */
/* Access to the winShmNode object is serialized by the caller */
assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
/* Release/Acquire the system-level lock */
if( lockType==_SHM_UNLCK ){
rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
}else{
/* Initialize the locking parameters */
DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
}
if( rc!= 0 ){
rc = SQLITE_OK;
}else{
pFile->lastErrno = osGetLastError();
rc = SQLITE_BUSY;
|
| ︙ | ︙ | |||
34989 34990 34991 34992 34993 34994 34995 |
}
pShmNode->aRegion = apNew;
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
| > > > > > | > > > > > > > | 33039 33040 33041 33042 33043 33044 33045 33046 33047 33048 33049 33050 33051 33052 33053 33054 33055 33056 33057 33058 33059 33060 33061 33062 33063 33064 33065 33066 33067 33068 33069 33070 33071 33072 33073 33074 33075 33076 |
}
pShmNode->aRegion = apNew;
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
NULL, PAGE_READWRITE, nByte, NULL
);
#else
hMap = osCreateFileMappingW(pShmNode->hFile.h,
NULL, PAGE_READWRITE, 0, nByte, NULL
);
#endif
OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
(int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
hMap ? "ok" : "failed"));
if( hMap ){
int iOffset = pShmNode->nRegion*szRegion;
int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
#if SQLITE_OS_WINRT
pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
iOffset - iOffsetShift, szRegion + iOffsetShift
);
#else
pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
0, iOffset - iOffsetShift, szRegion + iOffsetShift
);
#endif
OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
(int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
szRegion, pMap ? "ok" : "failed"));
}
if( !pMap ){
pShmNode->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
|
| ︙ | ︙ | |||
35086 35087 35088 35089 35090 35091 35092 |
** is obtained from malloc and must be freed by the calling
** function.
*/
static void *convertUtf8Filename(const char *zFilename){
void *zConverted = 0;
if( isNT() ){
zConverted = utf8ToUnicode(zFilename);
| < < > | | < > > > > > > | < < < < > | | < > > > > | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 33148 33149 33150 33151 33152 33153 33154 33155 33156 33157 33158 33159 33160 33161 33162 33163 33164 33165 33166 33167 33168 33169 33170 33171 33172 33173 33174 33175 33176 33177 33178 33179 33180 33181 33182 33183 33184 33185 33186 33187 33188 33189 33190 33191 33192 33193 33194 33195 33196 33197 33198 33199 33200 33201 33202 33203 33204 33205 33206 33207 33208 33209 33210 33211 33212 33213 33214 33215 33216 33217 33218 33219 33220 33221 33222 33223 33224 33225 33226 33227 33228 33229 33230 33231 33232 33233 33234 33235 33236 33237 33238 33239 33240 33241 33242 33243 33244 33245 33246 33247 33248 33249 33250 33251 33252 33253 33254 33255 33256 33257 33258 33259 33260 33261 33262 33263 33264 33265 33266 33267 33268 33269 33270 33271 33272 33273 33274 33275 33276 33277 33278 33279 |
** is obtained from malloc and must be freed by the calling
** function.
*/
static void *convertUtf8Filename(const char *zFilename){
void *zConverted = 0;
if( isNT() ){
zConverted = utf8ToUnicode(zFilename);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
}
#endif
/* caller will handle out of memory */
return zConverted;
}
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at pVfs->mxPathname characters.
*/
static int getTempname(int nBuf, char *zBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
int nTempPath;
char zTempPath[MAX_PATH+2];
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
SimulateIOError( return SQLITE_IOERR );
memset(zTempPath, 0, MAX_PATH+2);
if( sqlite3_temp_directory ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
}
#if !SQLITE_OS_WINRT
else if( isNT() ){
char *zMulti;
WCHAR zWidePath[MAX_PATH];
osGetTempPathW(MAX_PATH-30, zWidePath);
zMulti = unicodeToUtf8(zWidePath);
if( zMulti ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
sqlite3_free(zMulti);
}else{
return SQLITE_IOERR_NOMEM;
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zUtf8;
char zMbcsPath[MAX_PATH];
osGetTempPathA(MAX_PATH-30, zMbcsPath);
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
if( zUtf8 ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
sqlite3_free(zUtf8);
}else{
return SQLITE_IOERR_NOMEM;
}
}
#endif
#endif
/* Check that the output buffer is large enough for the temporary file
** name. If it is not, return SQLITE_ERROR.
*/
nTempPath = sqlite3Strlen30(zTempPath);
if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
return SQLITE_ERROR;
}
for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
zTempPath[i] = 0;
sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
"%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
zTempPath);
j = sqlite3Strlen30(zBuf);
sqlite3_randomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
}
zBuf[j] = 0;
zBuf[j+1] = 0;
OSTRACE(("TEMP FILENAME: %s\n", zBuf));
return SQLITE_OK;
}
/*
** Return TRUE if the named file is really a directory. Return false if
** it is something other than a directory, or if there is any kind of memory
** allocation failure.
*/
static int winIsDir(const void *zConverted){
DWORD attr;
int rc = 0;
DWORD lastErrno;
if( isNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
&sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
if( !rc ){
return 0; /* Invalid name? */
}
attr = sAttrData.dwFileAttributes;
#if SQLITE_OS_WINCE==0
}else{
attr = osGetFileAttributesA((char*)zConverted);
#endif
}
return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
}
/*
** Open a file.
*/
static int winOpen(
sqlite3_vfs *pVfs, /* Not used */
const char *zName, /* Name of the file (UTF-8) */
|
| ︙ | ︙ | |||
35276 35277 35278 35279 35280 35281 35282 35283 35284 35285 35286 35287 35288 35289 |
zUtf8Name[strlen(zUtf8Name)+1]==0 );
/* Convert the filename to the system encoding. */
zConverted = convertUtf8Filename(zUtf8Name);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isReadWrite ){
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
}else{
dwDesiredAccess = GENERIC_READ;
}
| > > > > > | 33372 33373 33374 33375 33376 33377 33378 33379 33380 33381 33382 33383 33384 33385 33386 33387 33388 33389 33390 |
zUtf8Name[strlen(zUtf8Name)+1]==0 );
/* Convert the filename to the system encoding. */
zConverted = convertUtf8Filename(zUtf8Name);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( winIsDir(zConverted) ){
sqlite3_free(zConverted);
return SQLITE_CANTOPEN_ISDIR;
}
if( isReadWrite ){
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
}else{
dwDesiredAccess = GENERIC_READ;
}
|
| ︙ | ︙ | |||
35320 35321 35322 35323 35324 35325 35326 35327 35328 35329 35330 35331 35332 |
/* Reports from the internet are that performance is always
** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
#if SQLITE_OS_WINCE
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif
if( isNT() ){
while( (h = osCreateFileW((LPCWSTR)zConverted,
dwDesiredAccess,
dwShareMode, NULL,
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
| > > > > > > > > > > > > > > > > > > | < < < | > > > | | | < > | | > | 33421 33422 33423 33424 33425 33426 33427 33428 33429 33430 33431 33432 33433 33434 33435 33436 33437 33438 33439 33440 33441 33442 33443 33444 33445 33446 33447 33448 33449 33450 33451 33452 33453 33454 33455 33456 33457 33458 33459 33460 33461 33462 33463 33464 33465 33466 33467 33468 33469 33470 33471 33472 33473 33474 33475 33476 |
/* Reports from the internet are that performance is always
** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
#if SQLITE_OS_WINCE
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif
if( isNT() ){
#if SQLITE_OS_WINRT
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
extendedParameters.dwFileAttributes =
dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParameters.lpSecurityAttributes = NULL;
extendedParameters.hTemplateFile = NULL;
while( (h = osCreateFile2((LPCWSTR)zConverted,
dwDesiredAccess,
dwShareMode,
dwCreationDisposition,
&extendedParameters))==INVALID_HANDLE_VALUE &&
retryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#else
while( (h = osCreateFileW((LPCWSTR)zConverted,
dwDesiredAccess,
dwShareMode, NULL,
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
retryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
while( (h = osCreateFileA((LPCSTR)zConverted,
dwDesiredAccess,
dwShareMode, NULL,
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
retryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
}
#endif
logIoerr(cnt);
OSTRACE(("OPEN %d %s 0x%lx %s\n",
h, zName, dwDesiredAccess,
h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
if( h==INVALID_HANDLE_VALUE ){
|
| ︙ | ︙ | |||
35419 35420 35421 35422 35423 35424 35425 35426 35427 35428 35429 35430 35431 35432 35433 35434 35435 35436 |
static int winDelete(
sqlite3_vfs *pVfs, /* Not used on win32 */
const char *zFilename, /* Name of file to delete */
int syncDir /* Not used on win32 */
){
int cnt = 0;
int rc;
DWORD lastErrno;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
SimulateIOError(return SQLITE_IOERR_DELETE);
zConverted = convertUtf8Filename(zFilename);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isNT() ){
| > > > > > > > > > | > > > | > > > > > > > > > > > > > | | < < < < > > > > | | | | > > > > > > > > > > > > | | | | > > > | 33539 33540 33541 33542 33543 33544 33545 33546 33547 33548 33549 33550 33551 33552 33553 33554 33555 33556 33557 33558 33559 33560 33561 33562 33563 33564 33565 33566 33567 33568 33569 33570 33571 33572 33573 33574 33575 33576 33577 33578 33579 33580 33581 33582 33583 33584 33585 33586 33587 33588 33589 33590 33591 33592 33593 33594 33595 33596 33597 33598 33599 33600 33601 33602 33603 33604 33605 33606 33607 33608 33609 33610 33611 33612 33613 33614 33615 33616 33617 33618 33619 |
static int winDelete(
sqlite3_vfs *pVfs, /* Not used on win32 */
const char *zFilename, /* Name of file to delete */
int syncDir /* Not used on win32 */
){
int cnt = 0;
int rc;
DWORD attr;
DWORD lastErrno;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
SimulateIOError(return SQLITE_IOERR_DELETE);
zConverted = convertUtf8Filename(zFilename);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isNT() ){
do {
#if SQLITE_OS_WINRT
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
&sAttrData) ){
attr = sAttrData.dwFileAttributes;
}else{
rc = SQLITE_OK; /* Already gone? */
break;
}
#else
attr = osGetFileAttributesW(zConverted);
#endif
if ( attr==INVALID_FILE_ATTRIBUTES ){
rc = SQLITE_OK; /* Already gone? */
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
rc = SQLITE_ERROR; /* Files only. */
break;
}
if ( osDeleteFileW(zConverted) ){
rc = SQLITE_OK; /* Deleted OK. */
break;
}
if ( !retryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
} while(1);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
do {
attr = osGetFileAttributesA(zConverted);
if ( attr==INVALID_FILE_ATTRIBUTES ){
rc = SQLITE_OK; /* Already gone? */
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
rc = SQLITE_ERROR; /* Files only. */
break;
}
if ( osDeleteFileA(zConverted) ){
rc = SQLITE_OK; /* Deleted OK. */
break;
}
if ( !retryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
} while(1);
}
#endif
if( rc ){
rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
"winDelete", zFilename);
}else{
logIoerr(cnt);
}
sqlite3_free(zConverted);
|
| ︙ | ︙ | |||
35505 35506 35507 35508 35509 35510 35511 |
winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
sqlite3_free(zConverted);
return SQLITE_IOERR_ACCESS;
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
}
| < < < < > | | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | < > > > > > > > > > > > | > | > > > > > > > | > > > < < < < > | | < > | | 33665 33666 33667 33668 33669 33670 33671 33672 33673 33674 33675 33676 33677 33678 33679 33680 33681 33682 33683 33684 33685 33686 33687 33688 33689 33690 33691 33692 33693 33694 33695 33696 33697 33698 33699 33700 33701 33702 33703 33704 33705 33706 33707 33708 33709 33710 33711 33712 33713 33714 33715 33716 33717 33718 33719 33720 33721 33722 33723 33724 33725 33726 33727 33728 33729 33730 33731 33732 33733 33734 33735 33736 33737 33738 33739 33740 33741 33742 33743 33744 33745 33746 33747 33748 33749 33750 33751 33752 33753 33754 33755 33756 33757 33758 33759 33760 33761 33762 33763 33764 33765 33766 33767 33768 33769 33770 33771 33772 33773 33774 33775 33776 33777 33778 33779 33780 33781 33782 33783 33784 33785 33786 33787 33788 33789 33790 33791 33792 33793 33794 33795 33796 33797 33798 33799 33800 33801 33802 33803 33804 33805 33806 33807 33808 33809 33810 33811 33812 33813 33814 33815 33816 33817 33818 33819 33820 33821 33822 33823 33824 33825 33826 33827 33828 33829 33830 33831 33832 33833 33834 33835 33836 33837 33838 33839 33840 33841 33842 33843 33844 33845 33846 33847 33848 33849 33850 33851 33852 33853 33854 33855 33856 33857 33858 33859 33860 33861 |
winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
sqlite3_free(zConverted);
return SQLITE_IOERR_ACCESS;
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
attr = osGetFileAttributesA((char*)zConverted);
}
#endif
sqlite3_free(zConverted);
switch( flags ){
case SQLITE_ACCESS_READ:
case SQLITE_ACCESS_EXISTS:
rc = attr!=INVALID_FILE_ATTRIBUTES;
break;
case SQLITE_ACCESS_READWRITE:
rc = attr!=INVALID_FILE_ATTRIBUTES &&
(attr & FILE_ATTRIBUTE_READONLY)==0;
break;
default:
assert(!"Invalid flags argument");
}
*pResOut = rc;
return SQLITE_OK;
}
/*
** Returns non-zero if the specified path name should be used verbatim. If
** non-zero is returned from this function, the calling function must simply
** use the provided path name verbatim -OR- resolve it into a full path name
** using the GetFullPathName Win32 API function (if available).
*/
static BOOL winIsVerbatimPathname(
const char *zPathname
){
/*
** If the path name starts with a forward slash or a backslash, it is either
** a legal UNC name, a volume relative path, or an absolute path name in the
** "Unix" format on Windows. There is no easy way to differentiate between
** the final two cases; therefore, we return the safer return value of TRUE
** so that callers of this function will simply use it verbatim.
*/
if ( zPathname[0]=='/' || zPathname[0]=='\\' ){
return TRUE;
}
/*
** If the path name starts with a letter and a colon it is either a volume
** relative path or an absolute path. Callers of this function must not
** attempt to treat it as a relative path name (i.e. they should simply use
** it verbatim).
*/
if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
return TRUE;
}
/*
** If we get to this point, the path name should almost certainly be a purely
** relative one (i.e. not a UNC name, not absolute, and not volume relative).
*/
return FALSE;
}
/*
** Turn a relative pathname into a full pathname. Write the full
** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
** bytes in size.
*/
static int winFullPathname(
sqlite3_vfs *pVfs, /* Pointer to vfs object */
const char *zRelative, /* Possibly relative input path */
int nFull, /* Size of output buffer in bytes */
char *zFull /* Output buffer */
){
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
assert( pVfs->mxPathname>=MAX_PATH );
assert( nFull>=pVfs->mxPathname );
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a slash.
*/
char zOut[MAX_PATH+1];
memset(zOut, 0, MAX_PATH+1);
cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
sqlite3_data_directory, zOut);
}else{
/*
** NOTE: The Cygwin docs state that the maximum length needed
** for the buffer passed to cygwin_conv_to_full_win32_path
** is MAX_PATH.
*/
cygwin_conv_to_full_win32_path(zRelative, zFull);
}
return SQLITE_OK;
#endif
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
/* WinCE has no concept of a relative pathname, or so I am told. */
/* WinRT has no way to convert a relative path to an absolute one. */
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
sqlite3_data_directory, zRelative);
}else{
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
}
return SQLITE_OK;
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
int nByte;
void *zConverted;
char *zOut;
/* If this path name begins with "/X:", where "X" is any alphabetic
** character, discard the initial "/" from the pathname.
*/
if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
zRelative++;
}
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing. This function could fail if, for example, the
** current working directory has been unlinked.
*/
SimulateIOError( return SQLITE_ERROR );
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
sqlite3_data_directory, zRelative);
return SQLITE_OK;
}
zConverted = convertUtf8Filename(zRelative);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isNT() ){
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
sqlite3_free(zConverted);
zOut = unicodeToUtf8(zTemp);
sqlite3_free(zTemp);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zTemp;
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
sqlite3_free(zTemp);
}
#endif
if( zOut ){
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
sqlite3_free(zOut);
return SQLITE_OK;
}else{
return SQLITE_IOERR_NOMEM;
}
#endif
}
|
| ︙ | ︙ | |||
35640 35641 35642 35643 35644 35645 35646 35647 |
HANDLE h;
void *zConverted = convertUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
if( zConverted==0 ){
return 0;
}
if( isNT() ){
h = osLoadLibraryW((LPCWSTR)zConverted);
| > > > < < < < > > | | < > | 33873 33874 33875 33876 33877 33878 33879 33880 33881 33882 33883 33884 33885 33886 33887 33888 33889 33890 33891 33892 33893 33894 33895 33896 33897 |
HANDLE h;
void *zConverted = convertUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
if( zConverted==0 ){
return 0;
}
if( isNT() ){
#if SQLITE_OS_WINRT
h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
#else
h = osLoadLibraryW((LPCWSTR)zConverted);
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
h = osLoadLibraryA((char*)zConverted);
}
#endif
sqlite3_free(zConverted);
return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
UNUSED_PARAMETER(pVfs);
getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
|
| ︙ | ︙ | |||
35694 35695 35696 35697 35698 35699 35700 35701 35702 35703 35704 35705 35706 35707 35708 35709 35710 35711 35712 35713 35714 35715 35716 35717 35718 35719 35720 |
n += sizeof(x);
}
if( sizeof(DWORD)<=nBuf-n ){
DWORD pid = osGetCurrentProcessId();
memcpy(&zBuf[n], &pid, sizeof(pid));
n += sizeof(pid);
}
if( sizeof(DWORD)<=nBuf-n ){
DWORD cnt = osGetTickCount();
memcpy(&zBuf[n], &cnt, sizeof(cnt));
n += sizeof(cnt);
}
if( sizeof(LARGE_INTEGER)<=nBuf-n ){
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
#endif
return n;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
static int winSleep(sqlite3_vfs *pVfs, int microsec){
| > > > > > > > > | | 33928 33929 33930 33931 33932 33933 33934 33935 33936 33937 33938 33939 33940 33941 33942 33943 33944 33945 33946 33947 33948 33949 33950 33951 33952 33953 33954 33955 33956 33957 33958 33959 33960 33961 33962 33963 33964 33965 33966 33967 33968 33969 33970 |
n += sizeof(x);
}
if( sizeof(DWORD)<=nBuf-n ){
DWORD pid = osGetCurrentProcessId();
memcpy(&zBuf[n], &pid, sizeof(pid));
n += sizeof(pid);
}
#if SQLITE_OS_WINRT
if( sizeof(ULONGLONG)<=nBuf-n ){
ULONGLONG cnt = osGetTickCount64();
memcpy(&zBuf[n], &cnt, sizeof(cnt));
n += sizeof(cnt);
}
#else
if( sizeof(DWORD)<=nBuf-n ){
DWORD cnt = osGetTickCount();
memcpy(&zBuf[n], &cnt, sizeof(cnt));
n += sizeof(cnt);
}
#endif
if( sizeof(LARGE_INTEGER)<=nBuf-n ){
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
#endif
return n;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
static int winSleep(sqlite3_vfs *pVfs, int microsec){
sqlite3_win32_sleep((microsec+999)/1000);
UNUSED_PARAMETER(pVfs);
return ((microsec+999)/1000)*1000;
}
/*
** The following variable, if set to a non-zero value, is interpreted as
** the number of seconds since 1970 and is used to set the result of
|
| ︙ | ︙ | |||
35856 35857 35858 35859 35860 35861 35862 |
winSetSystemCall, /* xSetSystemCall */
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
| | > > > > > > > > > > | 34098 34099 34100 34101 34102 34103 34104 34105 34106 34107 34108 34109 34110 34111 34112 34113 34114 34115 34116 34117 34118 34119 34120 34121 34122 34123 34124 34125 34126 34127 34128 34129 34130 34131 34132 34133 34134 34135 |
winSetSystemCall, /* xSetSystemCall */
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==73 );
#ifndef SQLITE_OMIT_WAL
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
osGetNativeSystemInfo(&winSysInfo);
#else
osGetSystemInfo(&winSysInfo);
#endif
assert(winSysInfo.dwAllocationGranularity > 0);
#endif
sqlite3_vfs_register(&winVfs, 1);
return SQLITE_OK;
}
SQLITE_API int sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj != NULL ){
osCloseHandle(sleepObj);
sleepObj = NULL;
}
#endif
return SQLITE_OK;
}
#endif /* SQLITE_OS_WIN */
/************** End of os_win.c **********************************************/
/************** Begin file bitvec.c ******************************************/
|
| ︙ | ︙ | |||
37121 37122 37123 37124 37125 37126 37127 37128 37129 37130 37131 37132 37133 37134 37135 37136 37137 37138 37139 37140 |
sqlite3_mutex_leave(pcache1.mutex);
}
if( p==0 ){
/* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get
** it from sqlite3Malloc instead.
*/
p = sqlite3Malloc(nByte);
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
}
return p;
}
/*
** Free an allocated buffer obtained from pcache1Alloc().
| > > | 35373 35374 35375 35376 35377 35378 35379 35380 35381 35382 35383 35384 35385 35386 35387 35388 35389 35390 35391 35392 35393 35394 |
sqlite3_mutex_leave(pcache1.mutex);
}
if( p==0 ){
/* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get
** it from sqlite3Malloc instead.
*/
p = sqlite3Malloc(nByte);
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
#endif
sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
}
return p;
}
/*
** Free an allocated buffer obtained from pcache1Alloc().
|
| ︙ | ︙ | |||
37153 37154 37155 37156 37157 37158 37159 37160 37161 37162 37163 37164 37165 37166 37167 37168 37169 |
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot<=pcache1.nSlot );
sqlite3_mutex_leave(pcache1.mutex);
}else{
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
nFreed = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
sqlite3_mutex_leave(pcache1.mutex);
sqlite3_free(p);
}
return nFreed;
}
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
| > > | 35407 35408 35409 35410 35411 35412 35413 35414 35415 35416 35417 35418 35419 35420 35421 35422 35423 35424 35425 |
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot<=pcache1.nSlot );
sqlite3_mutex_leave(pcache1.mutex);
}else{
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
nFreed = sqlite3MallocSize(p);
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
sqlite3_mutex_leave(pcache1.mutex);
#endif
sqlite3_free(p);
}
return nFreed;
}
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
|
| ︙ | ︙ | |||
41581 41582 41583 41584 41585 41586 41587 |
/* If a WAL transaction is being committed, there is no point in writing
** any pages with page numbers greater than nTruncate into the WAL file.
** They will never be read by any client. So remove them from the pDirty
** list here. */
PgHdr *p;
PgHdr **ppNext = &pList;
nList = 0;
| | | 39837 39838 39839 39840 39841 39842 39843 39844 39845 39846 39847 39848 39849 39850 39851 |
/* If a WAL transaction is being committed, there is no point in writing
** any pages with page numbers greater than nTruncate into the WAL file.
** They will never be read by any client. So remove them from the pDirty
** list here. */
PgHdr *p;
PgHdr **ppNext = &pList;
nList = 0;
for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
if( p->pgno<=nTruncate ){
ppNext = &p->pDirty;
nList++;
}
}
assert( pList );
}else{
|
| ︙ | ︙ | |||
42938 42939 42940 42941 42942 42943 42944 |
/* Set the output variable to NULL in case an error occurs. */
*ppPager = 0;
#ifndef SQLITE_OMIT_MEMORYDB
if( flags & PAGER_MEMORY ){
memDb = 1;
| > > > > | > | | 41194 41195 41196 41197 41198 41199 41200 41201 41202 41203 41204 41205 41206 41207 41208 41209 41210 41211 41212 41213 41214 41215 41216 41217 41218 41219 41220 41221 41222 41223 41224 |
/* Set the output variable to NULL in case an error occurs. */
*ppPager = 0;
#ifndef SQLITE_OMIT_MEMORYDB
if( flags & PAGER_MEMORY ){
memDb = 1;
if( zFilename && zFilename[0] ){
zPathname = sqlite3DbStrDup(0, zFilename);
if( zPathname==0 ) return SQLITE_NOMEM;
nPathname = sqlite3Strlen30(zPathname);
zFilename = 0;
}
}
#endif
/* Compute and store the full pathname in an allocated buffer pointed
** to by zPathname, length nPathname. Or, if this is a temporary file,
** leave both nPathname and zPathname set to 0.
*/
if( zFilename && zFilename[0] ){
const char *z;
nPathname = pVfs->mxPathname+1;
zPathname = sqlite3DbMallocRaw(0, nPathname*2);
if( zPathname==0 ){
return SQLITE_NOMEM;
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
nPathname = sqlite3Strlen30(zPathname);
z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
|
| ︙ | ︙ | |||
42973 42974 42975 42976 42977 42978 42979 |
** bytes in length. This means the database cannot be opened,
** as it will not be possible to open the journal file or even
** check for a hot-journal before reading.
*/
rc = SQLITE_CANTOPEN_BKPT;
}
if( rc!=SQLITE_OK ){
| | | 41234 41235 41236 41237 41238 41239 41240 41241 41242 41243 41244 41245 41246 41247 41248 |
** bytes in length. This means the database cannot be opened,
** as it will not be possible to open the journal file or even
** check for a hot-journal before reading.
*/
rc = SQLITE_CANTOPEN_BKPT;
}
if( rc!=SQLITE_OK ){
sqlite3DbFree(0, zPathname);
return rc;
}
}
/* Allocate memory for the Pager structure, PCache object, the
** three file descriptors, the database file name and the journal
** file name. The layout in memory is as follows:
|
| ︙ | ︙ | |||
43003 43004 43005 43006 43007 43008 43009 |
nPathname + 8 + 2 /* zJournal */
#ifndef SQLITE_OMIT_WAL
+ nPathname + 4 + 2 /* zWal */
#endif
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
| | | | | 41264 41265 41266 41267 41268 41269 41270 41271 41272 41273 41274 41275 41276 41277 41278 41279 41280 41281 41282 41283 41284 41285 41286 41287 41288 41289 41290 41291 41292 41293 41294 41295 41296 41297 41298 41299 41300 41301 41302 41303 41304 |
nPathname + 8 + 2 /* zJournal */
#ifndef SQLITE_OMIT_WAL
+ nPathname + 4 + 2 /* zWal */
#endif
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
return SQLITE_NOMEM;
}
pPager = (Pager*)(pPtr);
pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize);
pPager->zFilename = (char*)(pPtr += journalFileSize);
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
/* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
if( zPathname ){
assert( nPathname>0 );
pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri);
memcpy(pPager->zFilename, zPathname, nPathname);
if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
memcpy(pPager->zJournal, zPathname, nPathname);
memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1);
sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
pPager->zWal = &pPager->zJournal[nPathname+8+1];
memcpy(pPager->zWal, zPathname, nPathname);
memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
#endif
sqlite3DbFree(0, zPathname);
}
pPager->pVfs = pVfs;
pPager->vfsFlags = vfsFlags;
/* Open the pager file.
*/
if( zFilename && zFilename[0] ){
|
| ︙ | ︙ | |||
44874 44875 44876 44877 44878 44879 44880 44881 | } return rc; } /* ** Return the full pathname of the database file. */ | > > > > > > > | | | 43135 43136 43137 43138 43139 43140 43141 43142 43143 43144 43145 43146 43147 43148 43149 43150 43151 43152 43153 43154 43155 43156 43157 43158 |
}
return rc;
}
/*
** Return the full pathname of the database file.
**
** Except, if the pager is in-memory only, then return an empty string if
** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when
** used to report the filename to the user, for compatibility with legacy
** behavior. But when the Btree needs to know the filename for matching to
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
** participate in shared-cache.
*/
SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
}
/*
** Return the VFS structure for the pager.
*/
SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
return pPager->pVfs;
|
| ︙ | ︙ | |||
51261 51262 51263 51264 51265 51266 51267 | /* Set the variable isMemdb to true for an in-memory database, or ** false for a file-based database. */ #ifdef SQLITE_OMIT_MEMORYDB const int isMemdb = 0; #else const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) | | > | 49529 49530 49531 49532 49533 49534 49535 49536 49537 49538 49539 49540 49541 49542 49543 49544 |
/* Set the variable isMemdb to true for an in-memory database, or
** false for a file-based database.
*/
#ifdef SQLITE_OMIT_MEMORYDB
const int isMemdb = 0;
#else
const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0)
|| (isTempDb && sqlite3TempInMemory(db))
|| (vfsFlags & SQLITE_OPEN_MEMORY)!=0;
#endif
assert( db!=0 );
assert( pVfs!=0 );
assert( sqlite3_mutex_held(db->mutex) );
assert( (flags&0xff)==flags ); /* flags fit in 8 bits */
|
| ︙ | ︙ | |||
51297 51298 51299 51300 51301 51302 51303 | #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* ** If this Btree is a candidate for shared cache, try to find an ** existing BtShared object that we can share with */ | | > > > | > | | | | > | | 49566 49567 49568 49569 49570 49571 49572 49573 49574 49575 49576 49577 49578 49579 49580 49581 49582 49583 49584 49585 49586 49587 49588 49589 49590 49591 49592 49593 49594 49595 49596 49597 49598 49599 49600 49601 49602 49603 49604 49605 49606 49607 49608 49609 |
#endif
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/*
** If this Btree is a candidate for shared cache, try to find an
** existing BtShared object that we can share with
*/
if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
int nFullPathname = pVfs->mxPathname+1;
char *zFullPathname = sqlite3Malloc(nFullPathname);
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
return SQLITE_NOMEM;
}
if( isMemdb ){
memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
}else{
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
if( rc ){
sqlite3_free(zFullPathname);
sqlite3_free(p);
return rc;
}
}
#if SQLITE_THREADSAFE
mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
sqlite3_mutex_enter(mutexOpen);
mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
sqlite3_mutex_enter(mutexShared);
#endif
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
assert( pBt->nRef>0 );
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0))
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){
int iDb;
for(iDb=db->nDb-1; iDb>=0; iDb--){
Btree *pExisting = db->aDb[iDb].pBt;
if( pExisting && pExisting->pBt==pBt ){
sqlite3_mutex_leave(mutexShared);
sqlite3_mutex_leave(mutexOpen);
|
| ︙ | ︙ | |||
57586 57587 57588 57589 57590 57591 57592 | *pnErr = sCheck.nErr; if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); return sqlite3StrAccumFinish(&sCheck.errMsg); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* | | > | | 55860 55861 55862 55863 55864 55865 55866 55867 55868 55869 55870 55871 55872 55873 55874 55875 55876 55877 55878 55879 55880 55881 55882 |
*pnErr = sCheck.nErr;
if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
return sqlite3StrAccumFinish(&sCheck.errMsg);
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/*
** Return the full pathname of the underlying database file. Return
** an empty string if the database is in-memory or a TEMP database.
**
** The pager filename is invariant as long as the pager is
** open so it is safe to access without the BtShared mutex.
*/
SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){
assert( p->pBt->pPager!=0 );
return sqlite3PagerFilename(p->pBt->pPager, 1);
}
/*
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
**
|
| ︙ | ︙ | |||
58244 58245 58246 58247 58248 58249 58250 |
** the case where the source and destination databases have the
** same schema version.
*/
if( rc==SQLITE_DONE ){
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
if( rc==SQLITE_OK ){
if( p->pDestDb ){
| | | 56519 56520 56521 56522 56523 56524 56525 56526 56527 56528 56529 56530 56531 56532 56533 |
** the case where the source and destination databases have the
** same schema version.
*/
if( rc==SQLITE_DONE ){
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
if( rc==SQLITE_OK ){
if( p->pDestDb ){
sqlite3ResetAllSchemasOfConnection(p->pDestDb);
}
if( destMode==PAGER_JOURNALMODE_WAL ){
rc = sqlite3BtreeSetVersion(p->pDest, 2);
}
}
if( rc==SQLITE_OK ){
int nDestTruncate;
|
| ︙ | ︙ | |||
58373 58374 58375 58376 58377 58378 58379 |
}
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
| | > | < | 56648 56649 56650 56651 56652 56653 56654 56655 56656 56657 56658 56659 56660 56661 56662 56663 56664 56665 56666 56667 56668 56669 |
}
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
sqlite3 *pSrcDb; /* Source database connection */
int rc; /* Value to return */
/* Enter the mutexes */
if( p==0 ) return SQLITE_OK;
pSrcDb = p->pSrcDb;
sqlite3_mutex_enter(pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
if( p->pDestDb ){
sqlite3_mutex_enter(p->pDestDb->mutex);
}
/* Detach this backup from the source pager. */
if( p->pDestDb ){
p->pSrc->nBackup--;
|
| ︙ | ︙ | |||
58406 58407 58408 58409 58410 58411 58412 |
/* Set the error code of the destination database handle. */
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
sqlite3Error(p->pDestDb, rc, 0);
/* Exit the mutexes and free the backup context structure. */
if( p->pDestDb ){
| | | | 56681 56682 56683 56684 56685 56686 56687 56688 56689 56690 56691 56692 56693 56694 56695 56696 56697 56698 56699 56700 56701 56702 56703 56704 |
/* Set the error code of the destination database handle. */
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
sqlite3Error(p->pDestDb, rc, 0);
/* Exit the mutexes and free the backup context structure. */
if( p->pDestDb ){
sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
}
sqlite3BtreeLeave(p->pSrc);
if( p->pDestDb ){
/* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
** call to sqlite3_backup_init() and is destroyed by a call to
** sqlite3_backup_finish(). */
sqlite3_free(p);
}
sqlite3LeaveMutexAndCloseZombie(pSrcDb);
return rc;
}
/*
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
|
| ︙ | ︙ | |||
62179 62180 62181 62182 62183 62184 62185 62186 62187 62188 62189 62190 62191 62192 |
** Delete an entire VDBE.
*/
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
sqlite3 *db;
if( NEVER(p==0) ) return;
db = p->db;
if( p->pPrev ){
p->pPrev->pNext = p->pNext;
}else{
assert( db->pVdbe==p );
db->pVdbe = p->pNext;
}
if( p->pNext ){
| > | 60454 60455 60456 60457 60458 60459 60460 60461 60462 60463 60464 60465 60466 60467 60468 |
** Delete an entire VDBE.
*/
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
sqlite3 *db;
if( NEVER(p==0) ) return;
db = p->db;
assert( sqlite3_mutex_held(db->mutex) );
if( p->pPrev ){
p->pPrev->pNext = p->pNext;
}else{
assert( db->pVdbe==p );
db->pVdbe = p->pNext;
}
if( p->pNext ){
|
| ︙ | ︙ | |||
63018 63019 63020 63021 63022 63023 63024 |
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
** pointer is a harmless no-op. */
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite3 *db = v->db;
| < < < < < < | | | 61294 61295 61296 61297 61298 61299 61300 61301 61302 61303 61304 61305 61306 61307 61308 61309 61310 61311 61312 |
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
** pointer is a harmless no-op. */
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite3 *db = v->db;
if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
sqlite3_mutex_enter(db->mutex);
rc = sqlite3VdbeFinalize(v);
rc = sqlite3ApiExit(db, rc);
sqlite3LeaveMutexAndCloseZombie(db);
}
return rc;
}
/*
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from
|
| ︙ | ︙ | |||
64429 64430 64431 64432 64433 64434 64435 64436 |
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Allocate a new Explain object
*/
SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
if( pVdbe ){
sqlite3BeginBenignMalloc();
| > | | 62699 62700 62701 62702 62703 62704 62705 62706 62707 62708 62709 62710 62711 62712 62713 62714 62715 |
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Allocate a new Explain object
*/
SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
if( pVdbe ){
Explain *p;
sqlite3BeginBenignMalloc();
p = sqlite3_malloc( sizeof(Explain) );
if( p ){
memset(p, 0, sizeof(*p));
p->pVdbe = pVdbe;
sqlite3_free(pVdbe->pExplain);
pVdbe->pExplain = p;
sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
SQLITE_MAX_LENGTH);
|
| ︙ | ︙ | |||
67828 67829 67830 67831 67832 67833 67834 |
rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
| | | 66099 66100 66101 66102 66103 66104 66105 66106 66107 66108 66109 66110 66111 66112 66113 |
rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
db->flags = (db->flags | SQLITE_InternChanges);
}
}
/* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
** savepoints nested inside of the savepoint being operated on. */
while( db->pSavepoint!=u.ar.pSavepoint ){
|
| ︙ | ︙ | |||
68142 68143 68144 68145 68146 68147 68148 |
** prepared queries. If such a query is out-of-date, we do not want to
** discard the database schema, as the user code implementing the
** v-table would have to be ready for the sqlite3_vtab structure itself
** to be invalidated whenever sqlite3_step() is called from within
** a v-table method.
*/
if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){
| | | 66413 66414 66415 66416 66417 66418 66419 66420 66421 66422 66423 66424 66425 66426 66427 |
** prepared queries. If such a query is out-of-date, we do not want to
** discard the database schema, as the user code implementing the
** v-table would have to be ready for the sqlite3_vtab structure itself
** to be invalidated whenever sqlite3_step() is called from within
** a v-table method.
*/
if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){
sqlite3ResetOneSchema(db, pOp->p1);
}
p->expired = 1;
rc = SQLITE_SCHEMA;
}
break;
}
|
| ︙ | ︙ | |||
69335 69336 69337 69338 69339 69340 69341 | u.bl.pC = p->apCsr[pOp->p1]; assert( u.bl.pC->isSorter==0 ); assert( u.bl.pC->isTable || pOp->opcode!=OP_RowData ); assert( u.bl.pC->isIndex || pOp->opcode==OP_RowData ); assert( u.bl.pC!=0 ); assert( u.bl.pC->nullRow==0 ); assert( u.bl.pC->pseudoTableReg==0 ); | < | 67606 67607 67608 67609 67610 67611 67612 67613 67614 67615 67616 67617 67618 67619 | u.bl.pC = p->apCsr[pOp->p1]; assert( u.bl.pC->isSorter==0 ); assert( u.bl.pC->isTable || pOp->opcode!=OP_RowData ); assert( u.bl.pC->isIndex || pOp->opcode==OP_RowData ); assert( u.bl.pC!=0 ); assert( u.bl.pC->nullRow==0 ); assert( u.bl.pC->pseudoTableReg==0 ); assert( u.bl.pC->pCursor!=0 ); u.bl.pCrsr = u.bl.pC->pCursor; assert( sqlite3BtreeCursorIsValid(u.bl.pCrsr) ); /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or ** OP_Rewind/Op_Next with no intervening instructions that might invalidate ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| ︙ | ︙ | |||
70011 70012 70013 70014 70015 70016 70017 |
assert( !db->mallocFailed );
rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0);
if( rc==SQLITE_OK ) rc = u.by.initData.rc;
sqlite3DbFree(db, u.by.zSql);
db->init.busy = 0;
}
}
| | | 68281 68282 68283 68284 68285 68286 68287 68288 68289 68290 68291 68292 68293 68294 68295 |
assert( !db->mallocFailed );
rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0);
if( rc==SQLITE_OK ) rc = u.by.initData.rc;
sqlite3DbFree(db, u.by.zSql);
db->init.busy = 0;
}
}
if( rc ) sqlite3ResetAllSchemasOfConnection(db);
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
break;
}
#if !defined(SQLITE_OMIT_ANALYZE)
|
| ︙ | ︙ | |||
70678 70679 70680 70681 70682 70683 70684 | u.ci.pBt = db->aDb[pOp->p1].pBt; u.ci.pPager = sqlite3BtreePager(u.ci.pBt); u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager); if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld; if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld; #ifndef SQLITE_OMIT_WAL | | | 68948 68949 68950 68951 68952 68953 68954 68955 68956 68957 68958 68959 68960 68961 68962 |
u.ci.pBt = db->aDb[pOp->p1].pBt;
u.ci.pPager = sqlite3BtreePager(u.ci.pBt);
u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager);
if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld;
if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld;
#ifndef SQLITE_OMIT_WAL
u.ci.zFilename = sqlite3PagerFilename(u.ci.pPager, 1);
/* Do not allow a transition to journal_mode=WAL for a database
** in temporary storage or if the VFS does not support shared memory
*/
if( u.ci.eNew==PAGER_JOURNALMODE_WAL
&& (sqlite3Strlen30(u.ci.zFilename)==0 /* Temp file */
|| !sqlite3PagerWalSupported(u.ci.pPager)) /* No shared-memory support */
|
| ︙ | ︙ | |||
71344 71345 71346 71347 71348 71349 71350 |
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
pc, p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
| | | 69614 69615 69616 69617 69618 69619 69620 69621 69622 69623 69624 69625 69626 69627 69628 |
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
pc, p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
}
/* This is the only way out of this procedure. We have to
** release the mutexes on btrees that were acquired at the
** top. */
vdbe_return:
db->lastRowid = lastRowid;
|
| ︙ | ︙ | |||
73699 73700 73701 73702 73703 73704 73705 |
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
| | | 71969 71970 71971 71972 71973 71974 71975 71976 71977 71978 71979 71980 71981 71982 71983 |
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
resolveAlias(pParse, pEList, j, pExpr, "");
cnt = 1;
pMatch = 0;
assert( zTab==0 && zDb==0 );
|
| ︙ | ︙ | |||
73944 73945 73946 73947 73948 73949 73950 |
pNC->nErr++;
}
pExpr->op = TK_NULL;
return WRC_Prune;
}
}
#endif
| | | | | | | | 72214 72215 72216 72217 72218 72219 72220 72221 72222 72223 72224 72225 72226 72227 72228 72229 72230 72231 72232 72233 72234 72235 72236 72237 72238 72239 72240 72241 72242 72243 72244 72245 72246 72247 72248 72249 72250 72251 72252 72253 72254 72255 72256 72257 72258 72259 72260 72261 72262 72263 72264 72265 72266 72267 72268 72269 72270 72271 72272 72273 72274 72275 |
pNC->nErr++;
}
pExpr->op = TK_NULL;
return WRC_Prune;
}
}
#endif
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 ){
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
pNC->nErr++;
}else if( wrong_num_args ){
sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
nId, zId);
pNC->nErr++;
}
if( is_agg ){
pExpr->op = TK_AGG_FUNCTION;
pNC->ncFlags |= NC_HasAgg;
}
if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
sqlite3WalkExprList(pWalker, pList);
if( is_agg ) pNC->ncFlags |= NC_AllowAgg;
/* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function
*/
return WRC_Prune;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_SELECT:
case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
#ifndef SQLITE_OMIT_CHECK
if( (pNC->ncFlags & NC_IsCheck)!=0 ){
sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
}
#endif
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
}
}
break;
}
#ifndef SQLITE_OMIT_CHECK
case TK_VARIABLE: {
if( (pNC->ncFlags & NC_IsCheck)!=0 ){
sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
}
break;
}
#endif
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
|
| ︙ | ︙ | |||
74073 74074 74075 74076 74077 74078 74079 | /* Resolve all names in the ORDER BY term expression */ memset(&nc, 0, sizeof(nc)); nc.pParse = pParse; nc.pSrcList = pSelect->pSrc; nc.pEList = pEList; | | | 72343 72344 72345 72346 72347 72348 72349 72350 72351 72352 72353 72354 72355 72356 72357 | /* Resolve all names in the ORDER BY term expression */ memset(&nc, 0, sizeof(nc)); nc.pParse = pParse; nc.pSrcList = pSelect->pSrc; nc.pEList = pEList; nc.ncFlags = NC_AllowAgg; nc.nErr = 0; db = pParse->db; savedSuppErr = db->suppressErr; db->suppressErr = 1; rc = sqlite3ResolveExprNames(&nc, pE); db->suppressErr = savedSuppErr; if( rc ) return 0; |
| ︙ | ︙ | |||
74271 74272 74273 74274 74275 74276 74277 |
*/
static int resolveOrderGroupBy(
NameContext *pNC, /* The name context of the SELECT statement */
Select *pSelect, /* The SELECT statement holding pOrderBy */
ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */
const char *zType /* Either "ORDER" or "GROUP", as appropriate */
){
| | | 72541 72542 72543 72544 72545 72546 72547 72548 72549 72550 72551 72552 72553 72554 72555 |
*/
static int resolveOrderGroupBy(
NameContext *pNC, /* The name context of the SELECT statement */
Select *pSelect, /* The SELECT statement holding pOrderBy */
ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */
const char *zType /* Either "ORDER" or "GROUP", as appropriate */
){
int i, j; /* Loop counters */
int iCol; /* Column number */
struct ExprList_item *pItem; /* A term of the ORDER BY clause */
Parse *pParse; /* Parsing context */
int nResult; /* Number of terms in the result set */
if( pOrderBy==0 ) return 0;
nResult = pSelect->pEList->nExpr;
|
| ︙ | ︙ | |||
74307 74308 74309 74310 74311 74312 74313 74314 74315 74316 74317 74318 74319 74320 |
continue;
}
/* Otherwise, treat the ORDER BY term as an ordinary expression */
pItem->iOrderByCol = 0;
if( sqlite3ResolveExprNames(pNC, pE) ){
return 1;
}
}
return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}
/*
** Resolve names in the SELECT statement p and all of its descendents.
| > > > > > | 72577 72578 72579 72580 72581 72582 72583 72584 72585 72586 72587 72588 72589 72590 72591 72592 72593 72594 72595 |
continue;
}
/* Otherwise, treat the ORDER BY term as an ordinary expression */
pItem->iOrderByCol = 0;
if( sqlite3ResolveExprNames(pNC, pE) ){
return 1;
}
for(j=0; j<pSelect->pEList->nExpr; j++){
if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
pItem->iOrderByCol = j+1;
}
}
}
return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}
/*
** Resolve names in the SELECT statement p and all of its descendents.
|
| ︙ | ︙ | |||
74370 74371 74372 74373 74374 74375 74376 |
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
*/
| | | 72645 72646 72647 72648 72649 72650 72651 72652 72653 72654 72655 72656 72657 72658 72659 |
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
*/
sNC.ncFlags = NC_AllowAgg;
sNC.pSrcList = p->pSrc;
sNC.pNext = pOuterNC;
/* Resolve names in the result set. */
pEList = p->pEList;
assert( pEList!=0 );
for(i=0; i<pEList->nExpr; i++){
|
| ︙ | ︙ | |||
74416 74417 74418 74419 74420 74421 74422 |
}
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
pGroupBy = p->pGroupBy;
| | | | 72691 72692 72693 72694 72695 72696 72697 72698 72699 72700 72701 72702 72703 72704 72705 72706 72707 72708 |
}
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
pGroupBy = p->pGroupBy;
if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
p->selFlags |= SF_Aggregate;
}else{
sNC.ncFlags &= ~NC_AllowAgg;
}
/* If a HAVING clause is present, then there must be a GROUP BY clause.
*/
if( p->pHaving && !pGroupBy ){
sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
return WRC_Abort;
|
| ︙ | ︙ | |||
74448 74449 74450 74451 74452 74453 74454 |
return WRC_Abort;
}
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
| | | 72723 72724 72725 72726 72727 72728 72729 72730 72731 72732 72733 72734 72735 72736 72737 |
return WRC_Abort;
}
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
sNC.ncFlags |= NC_AllowAgg;
/* Process the ORDER BY clause for singleton SELECT statements.
** The ORDER BY clause for compounds SELECT statements is handled
** below, after all of the result-sets for all of the elements of
** the compound have been resolved.
*/
if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
|
| ︙ | ︙ | |||
74536 74537 74538 74539 74540 74541 74542 | ** ** The "x" term of the order by is replaced by "a+b" to render: ** ** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; ** ** Function calls are checked to make sure that the function is ** defined and that the correct number of arguments are specified. | | | | | | | | 72811 72812 72813 72814 72815 72816 72817 72818 72819 72820 72821 72822 72823 72824 72825 72826 72827 72828 72829 72830 72831 72832 72833 72834 72835 72836 72837 72838 72839 72840 72841 72842 72843 72844 72845 72846 72847 72848 72849 72850 72851 72852 72853 72854 72855 72856 72857 72858 72859 72860 72861 72862 72863 72864 72865 72866 |
**
** The "x" term of the order by is replaced by "a+b" to render:
**
** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b;
**
** Function calls are checked to make sure that the function is
** defined and that the correct number of arguments are specified.
** If the function is an aggregate function, then the NC_HasAgg flag is
** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION.
** If an expression contains aggregate functions then the EP_Agg
** property on the expression is set.
**
** An error message is left in pParse if anything is amiss. The number
** if errors is returned.
*/
SQLITE_PRIVATE int sqlite3ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */
){
u8 savedHasAgg;
Walker w;
if( pExpr==0 ) return 0;
#if SQLITE_MAX_EXPR_DEPTH>0
{
Parse *pParse = pNC->pParse;
if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){
return 1;
}
pParse->nHeight += pExpr->nHeight;
}
#endif
savedHasAgg = pNC->ncFlags & NC_HasAgg;
pNC->ncFlags &= ~NC_HasAgg;
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pNC->pParse;
w.u.pNC = pNC;
sqlite3WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
pNC->pParse->nHeight -= pExpr->nHeight;
#endif
if( pNC->nErr>0 || w.pParse->nErr>0 ){
ExprSetProperty(pExpr, EP_Error);
}
if( pNC->ncFlags & NC_HasAgg ){
ExprSetProperty(pExpr, EP_Agg);
}else if( savedHasAgg ){
pNC->ncFlags |= NC_HasAgg;
}
return ExprHasProperty(pExpr, EP_Error);
}
/*
** Resolve all names in all expressions of a SELECT and in all
|
| ︙ | ︙ | |||
78391 78392 78393 78394 78395 78396 78397 |
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
if( ExprHasProperty(pA, EP_IntValue) ){
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
return 2;
}
| | | 76666 76667 76668 76669 76670 76671 76672 76673 76674 76675 76676 76677 76678 76679 76680 |
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
if( ExprHasProperty(pA, EP_IntValue) ){
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
return 2;
}
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
}
}
if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
|
| ︙ | ︙ | |||
78578 78579 78580 78581 78582 78583 78584 |
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
}
return WRC_Prune;
}
case TK_AGG_FUNCTION: {
| > | > | 76853 76854 76855 76856 76857 76858 76859 76860 76861 76862 76863 76864 76865 76866 76867 76868 76869 |
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
}
return WRC_Prune;
}
case TK_AGG_FUNCTION: {
if( (pNC->ncFlags & NC_InAggFunc)==0
&& !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList)
){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
break;
|
| ︙ | ︙ | |||
78615 78616 78617 78618 78619 78620 78621 |
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
| < > > > | 76892 76893 76894 76895 76896 76897 76898 76899 76900 76901 76902 76903 76904 76905 76906 76907 76908 76909 76910 76911 76912 76913 76914 |
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
}
return WRC_Prune;
}
}
return WRC_Continue;
}
static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
UNUSED_PARAMETER(pWalker);
UNUSED_PARAMETER(pSelect);
return WRC_Continue;
}
/*
** Analyze the given expression looking for aggregate functions and
** for variables that need to be added to the pParse->aAgg[] array.
** Make additional entries to the pParse->aAgg[] array as necessary.
|
| ︙ | ︙ | |||
80898 80899 80900 80901 80902 80903 80904 |
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pBt ){
sqlite3BtreeClose(db->aDb[iDb].pBt);
db->aDb[iDb].pBt = 0;
db->aDb[iDb].pSchema = 0;
}
| | | 79177 79178 79179 79180 79181 79182 79183 79184 79185 79186 79187 79188 79189 79190 79191 |
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pBt ){
sqlite3BtreeClose(db->aDb[iDb].pBt);
db->aDb[iDb].pBt = 0;
db->aDb[iDb].pSchema = 0;
}
sqlite3ResetAllSchemasOfConnection(db);
db->nDb = iDb;
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
db->mallocFailed = 1;
sqlite3DbFree(db, zErrDyn);
zErrDyn = sqlite3MPrintf(db, "out of memory");
}else if( zErrDyn==0 ){
zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
|
| ︙ | ︙ | |||
80970 80971 80972 80973 80974 80975 80976 |
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
| | | 79249 79250 79251 79252 79253 79254 79255 79256 79257 79258 79259 79260 79261 79262 79263 |
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
sqlite3ResetAllSchemasOfConnection(db);
return;
detach_error:
sqlite3_result_error(context, zErr, -1);
}
/*
|
| ︙ | ︙ | |||
81886 81887 81888 81889 81890 81891 81892 |
}
freeIndex(db, pIndex);
}
db->flags |= SQLITE_InternChanges;
}
/*
| > | < | < < | < < > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 80165 80166 80167 80168 80169 80170 80171 80172 80173 80174 80175 80176 80177 80178 80179 80180 80181 80182 80183 80184 80185 80186 80187 80188 80189 80190 80191 80192 80193 80194 80195 80196 80197 80198 80199 80200 80201 80202 80203 80204 80205 80206 80207 80208 80209 80210 80211 80212 80213 80214 80215 80216 80217 80218 80219 80220 80221 80222 80223 80224 80225 80226 80227 80228 80229 80230 80231 80232 80233 80234 80235 80236 80237 80238 80239 80240 80241 80242 80243 80244 80245 80246 80247 80248 80249 80250 80251 80252 |
}
freeIndex(db, pIndex);
}
db->flags |= SQLITE_InternChanges;
}
/*
** Look through the list of open database files in db->aDb[] and if
** any have been closed, remove them from the list. Reallocate the
** db->aDb[] structure to a smaller size, if possible.
**
** Entry 0 (the "main" database) and entry 1 (the "temp" database)
** are never candidates for being collapsed.
*/
SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
int i, j;
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
sqlite3DbFree(db, pDb->zName);
pDb->zName = 0;
continue;
}
if( j<i ){
db->aDb[j] = db->aDb[i];
}
j++;
}
memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
db->nDb = j;
if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
sqlite3DbFree(db, db->aDb);
db->aDb = db->aDbStatic;
}
}
/*
** Reset the schema for the database at index iDb. Also reset the
** TEMP schema.
*/
SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
Db *pDb;
assert( iDb<db->nDb );
/* Case 1: Reset the single schema identified by iDb */
pDb = &db->aDb[iDb];
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
assert( pDb->pSchema!=0 );
sqlite3SchemaClear(pDb->pSchema);
/* If any database other than TEMP is reset, then also reset TEMP
** since TEMP might be holding triggers that reference tables in the
** other database.
*/
if( iDb!=1 ){
pDb = &db->aDb[1];
assert( pDb->pSchema!=0 );
sqlite3SchemaClear(pDb->pSchema);
}
return;
}
/*
** Erase all schema information from all attached databases (including
** "main" and "temp") for a single database connection.
*/
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
int i;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
sqlite3SchemaClear(pDb->pSchema);
}
}
db->flags &= ~SQLITE_InternChanges;
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
sqlite3CollapseDatabaseArray(db);
}
/*
** This routine is called when a commit occurs.
*/
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
db->flags &= ~SQLITE_InternChanges;
}
|
| ︙ | ︙ | |||
81994 81995 81996 81997 81998 81999 82000 82001 82002 82003 82004 82005 82006 82007 82008 82009 82010 82011 82012 82013 82014 82015 82016 |
** Remove the memory data structures associated with the given
** Table. No changes are made to disk by this routine.
**
** This routine just deletes the data structure. It does not unlink
** the table data structure from the hash table. But it does destroy
** memory structures of the indices and foreign keys associated with
** the table.
*/
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
Index *pIndex, *pNext;
assert( !pTable || pTable->nRef>0 );
/* Do not delete the table until the reference count reaches zero. */
if( !pTable ) return;
if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
| > > > > > > > > > > > > > | 80275 80276 80277 80278 80279 80280 80281 80282 80283 80284 80285 80286 80287 80288 80289 80290 80291 80292 80293 80294 80295 80296 80297 80298 80299 80300 80301 80302 80303 80304 80305 80306 80307 80308 80309 80310 |
** Remove the memory data structures associated with the given
** Table. No changes are made to disk by this routine.
**
** This routine just deletes the data structure. It does not unlink
** the table data structure from the hash table. But it does destroy
** memory structures of the indices and foreign keys associated with
** the table.
**
** The db parameter is optional. It is needed if the Table object
** contains lookaside memory. (Table objects in the schema do not use
** lookaside memory, but some ephemeral Table objects do.) Or the
** db parameter can be used with db->pnBytesFreed to measure the memory
** used by the Table object.
*/
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
Index *pIndex, *pNext;
TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
assert( !pTable || pTable->nRef>0 );
/* Do not delete the table until the reference count reaches zero. */
if( !pTable ) return;
if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
/* Record the number of outstanding lookaside allocations in schema Tables
** prior to doing any free() operations. Since schema Tables do not use
** lookaside, this number should not change. */
TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ?
db->lookaside.nOut : 0 );
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
|
| ︙ | ︙ | |||
82035 82036 82037 82038 82039 82040 82041 82042 82043 82044 82045 82046 82047 82048 |
#ifndef SQLITE_OMIT_CHECK
sqlite3ExprListDelete(db, pTable->pCheck);
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3VtabClear(db, pTable);
#endif
sqlite3DbFree(db, pTable);
}
/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
| > > > | 80329 80330 80331 80332 80333 80334 80335 80336 80337 80338 80339 80340 80341 80342 80343 80344 80345 |
#ifndef SQLITE_OMIT_CHECK
sqlite3ExprListDelete(db, pTable->pCheck);
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3VtabClear(db, pTable);
#endif
sqlite3DbFree(db, pTable);
/* Verify that no lookaside memory was used by schema tables */
assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
}
/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
|
| ︙ | ︙ | |||
82983 82984 82985 82986 82987 82988 82989 |
memset(&sSrc, 0, sizeof(sSrc));
sSrc.nSrc = 1;
sSrc.a[0].zName = p->zName;
sSrc.a[0].pTab = p;
sSrc.a[0].iCursor = -1;
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
| | | 81280 81281 81282 81283 81284 81285 81286 81287 81288 81289 81290 81291 81292 81293 81294 |
memset(&sSrc, 0, sizeof(sSrc));
sSrc.nSrc = 1;
sSrc.a[0].zName = p->zName;
sSrc.a[0].pTab = p;
sSrc.a[0].iCursor = -1;
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
sNC.ncFlags = NC_IsCheck;
pList = p->pCheck;
for(i=0; i<pList->nExpr; i++){
if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
return;
}
}
}
|
| ︙ | ︙ | |||
84239 84240 84241 84242 84243 84244 84245 |
memcpy(zExtra, zColl, nColl);
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
if( !zColl ){
| | | 82536 82537 82538 82539 82540 82541 82542 82543 82544 82545 82546 82547 82548 82549 82550 |
memcpy(zExtra, zColl, nColl);
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
if( !zColl ){
zColl = "BINARY";
}
}
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
|
| ︙ | ︙ | |||
87310 87311 87312 87313 87314 87315 87316 |
** "NULL". Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite3_value_type(argv[0]) ){
| | > > > > > > > > > > > | | 85607 85608 85609 85610 85611 85612 85613 85614 85615 85616 85617 85618 85619 85620 85621 85622 85623 85624 85625 85626 85627 85628 85629 85630 85631 85632 85633 |
** "NULL". Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_FLOAT: {
double r1, r2;
char zBuf[50];
r1 = sqlite3_value_double(argv[0]);
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
if( r1!=r2 ){
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
}
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
break;
}
case SQLITE_INTEGER: {
sqlite3_result_value(context, argv[0]);
break;
}
case SQLITE_BLOB: {
char *zText = 0;
char const *zBlob = sqlite3_value_blob(argv[0]);
int nBlob = sqlite3_value_bytes(argv[0]);
|
| ︙ | ︙ | |||
92514 92515 92516 92517 92518 92519 92520 |
if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
"from within a transaction");
return SQLITE_ERROR;
}
sqlite3BtreeClose(db->aDb[1].pBt);
db->aDb[1].pBt = 0;
| | | 90822 90823 90824 90825 90826 90827 90828 90829 90830 90831 90832 90833 90834 90835 90836 |
if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
"from within a transaction");
return SQLITE_ERROR;
}
sqlite3BtreeClose(db->aDb[1].pBt);
db->aDb[1].pBt = 0;
sqlite3ResetAllSchemasOfConnection(db);
}
return SQLITE_OK;
}
#endif /* SQLITE_PAGER_PRAGMAS */
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
|
| ︙ | ︙ | |||
93199 93200 93201 93202 93203 93204 93205 93206 93207 93208 93209 93210 93211 93212 |
sqlite3_temp_directory = sqlite3_mprintf("%s", zRight);
}else{
sqlite3_temp_directory = 0;
}
#endif /* SQLITE_OMIT_WSD */
}
}else
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
# if defined(__APPLE__)
# define SQLITE_ENABLE_LOCKING_STYLE 1
# else
# define SQLITE_ENABLE_LOCKING_STYLE 0
# endif
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 91507 91508 91509 91510 91511 91512 91513 91514 91515 91516 91517 91518 91519 91520 91521 91522 91523 91524 91525 91526 91527 91528 91529 91530 91531 91532 91533 91534 91535 91536 91537 91538 91539 91540 91541 91542 91543 91544 91545 91546 91547 91548 91549 91550 91551 91552 91553 91554 91555 91556 91557 91558 91559 91560 91561 91562 91563 91564 |
sqlite3_temp_directory = sqlite3_mprintf("%s", zRight);
}else{
sqlite3_temp_directory = 0;
}
#endif /* SQLITE_OMIT_WSD */
}
}else
#if SQLITE_OS_WIN
/*
** PRAGMA data_store_directory
** PRAGMA data_store_directory = ""|"directory_name"
**
** Return or set the local value of the data_store_directory flag. Changing
** the value sets a specific directory to be used for database files that
** were specified with a relative pathname. Setting to a null string reverts
** to the default database directory, which for database files specified with
** a relative path will probably be based on the current directory for the
** process. Database file specified with an absolute path are not impacted
** by this setting, regardless of its value.
**
*/
if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){
if( !zRight ){
if( sqlite3_data_directory ){
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
"data_store_directory", SQLITE_STATIC);
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
int res;
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
if( rc!=SQLITE_OK || res==0 ){
sqlite3ErrorMsg(pParse, "not a writable directory");
goto pragma_out;
}
}
sqlite3_free(sqlite3_data_directory);
if( zRight[0] ){
sqlite3_data_directory = sqlite3_mprintf("%s", zRight);
}else{
sqlite3_data_directory = 0;
}
#endif /* SQLITE_OMIT_WSD */
}
}else
#endif
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
# if defined(__APPLE__)
# define SQLITE_ENABLE_LOCKING_STYLE 1
# else
# define SQLITE_ENABLE_LOCKING_STYLE 0
# endif
|
| ︙ | ︙ | |||
94232 94233 94234 94235 94236 94237 94238 |
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
if( iDb==0 ){
u8 encoding;
/* If opening the main database, set ENC(db). */
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
if( encoding==0 ) encoding = SQLITE_UTF8;
ENC(db) = encoding;
| < | 92584 92585 92586 92587 92588 92589 92590 92591 92592 92593 92594 92595 92596 92597 |
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
if( iDb==0 ){
u8 encoding;
/* If opening the main database, set ENC(db). */
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
if( encoding==0 ) encoding = SQLITE_UTF8;
ENC(db) = encoding;
}else{
/* If opening an attached database, the encoding much match ENC(db) */
if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
" text encoding as main database");
rc = SQLITE_ERROR;
goto initone_error_out;
|
| ︙ | ︙ | |||
94312 94313 94314 94315 94316 94317 94318 |
if( rc==SQLITE_OK ){
sqlite3AnalysisLoad(db, iDb);
}
#endif
}
if( db->mallocFailed ){
rc = SQLITE_NOMEM;
| | | 92663 92664 92665 92666 92667 92668 92669 92670 92671 92672 92673 92674 92675 92676 92677 |
if( rc==SQLITE_OK ){
sqlite3AnalysisLoad(db, iDb);
}
#endif
}
if( db->mallocFailed ){
rc = SQLITE_NOMEM;
sqlite3ResetAllSchemasOfConnection(db);
}
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
/* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
** the schema loaded, even if errors occurred. In this situation the
** current sqlite3_prepare() operation will fail, but the following one
** will attempt to compile the supplied statement against whatever subset
** of the schema was loaded before the error occurred. The primary
|
| ︙ | ︙ | |||
94365 94366 94367 94368 94369 94370 94371 |
assert( sqlite3_mutex_held(db->mutex) );
rc = SQLITE_OK;
db->init.busy = 1;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
rc = sqlite3InitOne(db, i, pzErrMsg);
if( rc ){
| | | | 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 |
assert( sqlite3_mutex_held(db->mutex) );
rc = SQLITE_OK;
db->init.busy = 1;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
rc = sqlite3InitOne(db, i, pzErrMsg);
if( rc ){
sqlite3ResetOneSchema(db, i);
}
}
/* Once all the other databases have been initialised, load the schema
** for the TEMP database. This is loaded last, as the TEMP database
** schema may contain references to objects in other databases.
*/
#ifndef SQLITE_OMIT_TEMPDB
if( rc==SQLITE_OK && ALWAYS(db->nDb>1)
&& !DbHasProperty(db, 1, DB_SchemaLoaded) ){
rc = sqlite3InitOne(db, 1, pzErrMsg);
if( rc ){
sqlite3ResetOneSchema(db, 1);
}
}
#endif
db->init.busy = 0;
if( rc==SQLITE_OK && commit_internal ){
sqlite3CommitInternalChanges(db);
|
| ︙ | ︙ | |||
94446 94447 94448 94449 94450 94451 94452 |
/* Read the schema cookie from the database. If it does not match the
** value stored as part of the in-memory schema representation,
** set Parse.rc to SQLITE_SCHEMA. */
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
| | | 92797 92798 92799 92800 92801 92802 92803 92804 92805 92806 92807 92808 92809 92810 92811 |
/* Read the schema cookie from the database. If it does not match the
** value stored as part of the in-memory schema representation,
** set Parse.rc to SQLITE_SCHEMA. */
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
sqlite3ResetOneSchema(db, iDb);
pParse->rc = SQLITE_SCHEMA;
}
/* Close the transaction, if one was opened. */
if( openedTransaction ){
sqlite3BtreeCommit(pBt);
}
|
| ︙ | ︙ | |||
94676 94677 94678 94679 94680 94681 94682 94683 94684 94685 94686 94687 94688 94689 |
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
if( rc==SQLITE_SCHEMA ){
sqlite3_finalize(*ppStmt);
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
}
sqlite3BtreeLeaveAll(db);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** Rerun the compilation of a statement after a schema change.
**
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
| > | 93027 93028 93029 93030 93031 93032 93033 93034 93035 93036 93037 93038 93039 93040 93041 |
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
if( rc==SQLITE_SCHEMA ){
sqlite3_finalize(*ppStmt);
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
}
sqlite3BtreeLeaveAll(db);
sqlite3_mutex_leave(db->mutex);
assert( rc==SQLITE_OK || *ppStmt==0 );
return rc;
}
/*
** Rerun the compilation of a statement after a schema change.
**
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
|
| ︙ | ︙ | |||
97983 97984 97985 97986 97987 97988 97989 97990 97991 97992 97993 97994 97995 97996 | } pTab = p->pSrc->a[0].pTab; pExpr = p->pEList->a[0].pExpr; assert( pTab && !pTab->pSelect && pExpr ); if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; if( pExpr->flags&EP_Distinct ) return 0; return pTab; } /* | > | 96335 96336 96337 96338 96339 96340 96341 96342 96343 96344 96345 96346 96347 96348 96349 | } pTab = p->pSrc->a[0].pTab; pExpr = p->pEList->a[0].pExpr; assert( pTab && !pTab->pSelect && pExpr ); if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( pAggInfo->nFunc==0 ) return 0; if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; if( pExpr->flags&EP_Distinct ) return 0; return pTab; } /* |
| ︙ | ︙ | |||
98973 98974 98975 98976 98977 98978 98979 98980 98981 98982 98983 98984 98985 98986 98987 |
sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
if( pHaving ){
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
}
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
*/
if( pGroupBy ){
| > > | 97326 97327 97328 97329 97330 97331 97332 97333 97334 97335 97336 97337 97338 97339 97340 97341 97342 |
sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
if( pHaving ){
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sNC.ncFlags |= NC_InAggFunc;
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
}
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
*/
if( pGroupBy ){
|
| ︙ | ︙ | |||
101795 101796 101797 101798 101799 101800 101801 |
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
}
/* This both clears the schemas and reduces the size of the db->aDb[]
** array. */
| | | 100150 100151 100152 100153 100154 100155 100156 100157 100158 100159 100160 100161 100162 100163 100164 |
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
}
/* This both clears the schemas and reduces the size of the db->aDb[]
** array. */
sqlite3ResetAllSchemasOfConnection(db);
return rc;
}
#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
/************** End of vacuum.c **********************************************/
|
| ︙ | ︙ | |||
101827 101828 101829 101830 101831 101832 101833 |
** Before a virtual table xCreate() or xConnect() method is invoked, the
** sqlite3.pVtabCtx member variable is set to point to an instance of
** this struct allocated on the stack. It is used by the implementation of
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
| < | > > | < > > > > | | | | | | | | | | | < < < < | | > | < < | > | > > | 100182 100183 100184 100185 100186 100187 100188 100189 100190 100191 100192 100193 100194 100195 100196 100197 100198 100199 100200 100201 100202 100203 100204 100205 100206 100207 100208 100209 100210 100211 100212 100213 100214 100215 100216 100217 100218 100219 100220 100221 100222 100223 100224 100225 100226 100227 100228 100229 100230 100231 100232 100233 100234 100235 100236 100237 100238 100239 100240 |
** Before a virtual table xCreate() or xConnect() method is invoked, the
** sqlite3.pVtabCtx member variable is set to point to an instance of
** this struct allocated on the stack. It is used by the implementation of
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
VTable *pVTable; /* The virtual table being constructed */
Table *pTab; /* The Table object to which the virtual table belongs */
};
/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
*/
static int createModule(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
void *pAux, /* Context pointer for xCreate/xConnect */
void (*xDestroy)(void *) /* Module destructor function */
){
int rc = SQLITE_OK;
int nName;
sqlite3_mutex_enter(db->mutex);
nName = sqlite3Strlen30(zName);
if( sqlite3HashFind(&db->aModule, zName, nName) ){
rc = SQLITE_MISUSE_BKPT;
}else{
Module *pMod;
pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
if( pMod ){
Module *pDel;
char *zCopy = (char *)(&pMod[1]);
memcpy(zCopy, zName, nName+1);
pMod->zName = zCopy;
pMod->pModule = pModule;
pMod->pAux = pAux;
pMod->xDestroy = xDestroy;
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod);
assert( pDel==0 || pDel==pMod );
if( pDel ){
db->mallocFailed = 1;
sqlite3DbFree(db, pDel);
}
}
}
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** External API function used to create a new virtual-table module.
|
| ︙ | ︙ | |||
101984 101985 101986 101987 101988 101989 101990 101991 101992 101993 101994 101995 101996 101997 |
}
pVTable = pNext;
}
assert( !db || pRet );
return pRet;
}
/*
** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
**
** This function may only be called when the mutexes associated with all
** shared b-tree databases opened using connection db are held by the
| > > > > > > > > > > > > > > > > > > > > > > > > > | 100341 100342 100343 100344 100345 100346 100347 100348 100349 100350 100351 100352 100353 100354 100355 100356 100357 100358 100359 100360 100361 100362 100363 100364 100365 100366 100367 100368 100369 100370 100371 100372 100373 100374 100375 100376 100377 100378 100379 |
}
pVTable = pNext;
}
assert( !db || pRet );
return pRet;
}
/*
** Table *p is a virtual table. This function removes the VTable object
** for table *p associated with database connection db from the linked
** list in p->pVTab. It also decrements the VTable ref count. This is
** used when closing database connection db to free all of its VTable
** objects without disturbing the rest of the Schema object (which may
** be being used by other shared-cache connections).
*/
SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){
VTable **ppVTab;
assert( IsVirtual(p) );
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3_mutex_held(db->mutex) );
for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){
if( (*ppVTab)->db==db ){
VTable *pVTab = *ppVTab;
*ppVTab = pVTab->pNext;
sqlite3VtabUnlock(pVTab);
break;
}
}
}
/*
** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
**
** This function may only be called when the mutexes associated with all
** shared b-tree databases opened using connection db are held by the
|
| ︙ | ︙ | |||
102252 102253 102254 102255 102256 102257 102258 |
static int vtabCallConstructor(
sqlite3 *db,
Table *pTab,
Module *pMod,
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
| | | 100634 100635 100636 100637 100638 100639 100640 100641 100642 100643 100644 100645 100646 100647 100648 |
static int vtabCallConstructor(
sqlite3 *db,
Table *pTab,
Module *pMod,
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
VtabCtx sCtx, *pPriorCtx;
VTable *pVTable;
int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg;
char *zErr = 0;
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
|
| ︙ | ︙ | |||
102277 102278 102279 102280 102281 102282 102283 102284 102285 | pVTable->pMod = pMod; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); assert( xConstruct ); sCtx.pTab = pTab; sCtx.pVTable = pVTable; db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); | > | | 100659 100660 100661 100662 100663 100664 100665 100666 100667 100668 100669 100670 100671 100672 100673 100674 100675 100676 |
pVTable->pMod = pMod;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
pPriorCtx = db->pVtabCtx;
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = pPriorCtx;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
if( SQLITE_OK!=rc ){
if( zErr==0 ){
*pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
}else {
*pzErr = sqlite3MPrintf(db, "%s", zErr);
|
| ︙ | ︙ | |||
104436 104437 104438 104439 104440 104441 104442 104443 104444 104445 104446 104447 |
**
** 1. The index is itself UNIQUE, and
**
** 2. All of the columns in the index are either part of the pDistinct
** list, or else the WHERE clause contains a term of the form "col=X",
** where X is a constant value. The collation sequences of the
** comparison and select-list expressions must match those of the index.
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None ) continue;
for(i=0; i<pIdx->nColumn; i++){
int iCol = pIdx->aiColumn[i];
| > > > | | | | > | 102819 102820 102821 102822 102823 102824 102825 102826 102827 102828 102829 102830 102831 102832 102833 102834 102835 102836 102837 102838 102839 102840 102841 102842 102843 102844 102845 |
**
** 1. The index is itself UNIQUE, and
**
** 2. All of the columns in the index are either part of the pDistinct
** list, or else the WHERE clause contains a term of the form "col=X",
** where X is a constant value. The collation sequences of the
** comparison and select-list expressions must match those of the index.
**
** 3. All of those index columns for which the WHERE clause does not
** contain a "col=X" term are subject to a NOT NULL constraint.
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None ) continue;
for(i=0; i<pIdx->nColumn; i++){
int iCol = pIdx->aiColumn[i];
if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){
break;
}
}
}
if( i==pIdx->nColumn ){
/* This index implies that the DISTINCT qualifier is redundant. */
return 1;
}
}
|
| ︙ | ︙ | |||
104592 104593 104594 104595 104596 104597 104598 |
if( j>=nTerm ){
/* All terms of the ORDER BY clause are covered by this index so
** this index can be used for sorting. */
return 1;
}
if( pIdx->onError!=OE_None && i==pIdx->nColumn
&& (wsFlags & WHERE_COLUMN_NULL)==0
| | > > > | | | > | > | > > > | > > > | | 102979 102980 102981 102982 102983 102984 102985 102986 102987 102988 102989 102990 102991 102992 102993 102994 102995 102996 102997 102998 102999 103000 103001 103002 103003 103004 103005 103006 103007 103008 103009 103010 103011 |
if( j>=nTerm ){
/* All terms of the ORDER BY clause are covered by this index so
** this index can be used for sorting. */
return 1;
}
if( pIdx->onError!=OE_None && i==pIdx->nColumn
&& (wsFlags & WHERE_COLUMN_NULL)==0
&& !referencesOtherTables(pOrderBy, pMaskSet, j, base)
){
Column *aCol = pIdx->pTable->aCol;
/* All terms of this index match some prefix of the ORDER BY clause,
** the index is UNIQUE, and no terms on the tail of the ORDER BY
** refer to other tables in a join. So, assuming that the index entries
** visited contain no NULL values, then this index delivers rows in
** the required order.
**
** It is not possible for any of the first nEqCol index fields to be
** NULL (since the corresponding "=" operator in the WHERE clause would
** not be true). So if all remaining index columns have NOT NULL
** constaints attached to them, we can be confident that the visited
** index entries are free of NULLs. */
for(i=nEqCol; i<pIdx->nColumn; i++){
if( aCol[pIdx->aiColumn[i]].notNull==0 ) break;
}
return (i==pIdx->nColumn);
}
return 0;
}
/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact. This is only used for estimating
|
| ︙ | ︙ | |||
108353 108354 108355 108356 108357 108358 108359 | #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse #define YYNSTATE 627 | | | 106751 106752 106753 106754 106755 106756 106757 106758 106759 106760 106761 106762 106763 106764 106765 | #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse #define YYNSTATE 627 #define YYNRULE 327 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) /* The yyzerominor constant is used to initialize instances of ** YYMINORTYPE objects to zero. */ |
| ︙ | ︙ | |||
108423 108424 108425 108426 108427 108428 108429 | ** yy_action. Used to detect hash collisions. ** yy_shift_ofst[] For each state, the offset into yy_action for ** shifting terminals. ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 106821 106822 106823 106824 106825 106826 106827 106828 106829 106830 106831 106832 106833 106834 106835 106836 106837 106838 106839 106840 106841 106842 106843 106844 106845 106846 106847 106848 106849 106850 106851 106852 106853 106854 106855 106856 106857 106858 106859 106860 106861 106862 106863 106864 106865 106866 106867 106868 106869 106870 106871 106872 106873 106874 106875 106876 106877 106878 106879 106880 106881 106882 106883 106884 106885 106886 106887 106888 106889 106890 106891 106892 106893 106894 106895 106896 106897 106898 106899 106900 106901 106902 106903 106904 106905 106906 106907 106908 106909 106910 106911 106912 106913 106914 106915 106916 106917 106918 106919 106920 106921 106922 106923 106924 106925 106926 106927 106928 106929 106930 106931 106932 106933 106934 106935 106936 106937 106938 106939 106940 106941 106942 106943 106944 106945 106946 106947 106948 106949 106950 106951 106952 106953 106954 106955 106956 106957 106958 106959 106960 106961 106962 106963 106964 106965 106966 106967 106968 106969 106970 106971 106972 106973 106974 106975 106976 106977 106978 106979 106980 106981 106982 106983 106984 106985 106986 106987 106988 106989 106990 106991 106992 106993 106994 106995 106996 106997 106998 106999 107000 107001 107002 107003 107004 107005 107006 107007 107008 107009 107010 107011 107012 107013 107014 107015 107016 107017 107018 107019 107020 107021 107022 107023 107024 107025 107026 107027 107028 107029 107030 107031 107032 107033 107034 107035 107036 107037 107038 107039 107040 107041 107042 107043 107044 107045 107046 107047 107048 107049 107050 107051 107052 107053 107054 107055 107056 107057 107058 107059 107060 107061 107062 107063 107064 107065 107066 107067 107068 107069 107070 107071 107072 107073 107074 107075 107076 107077 107078 107079 107080 107081 107082 107083 107084 107085 107086 107087 107088 107089 107090 107091 107092 107093 107094 107095 107096 107097 107098 107099 107100 107101 107102 107103 107104 107105 107106 107107 107108 107109 107110 107111 107112 107113 107114 107115 107116 107117 107118 107119 107120 107121 107122 107123 107124 107125 107126 107127 107128 107129 107130 107131 107132 107133 107134 107135 107136 107137 107138 107139 107140 107141 107142 107143 107144 107145 107146 107147 107148 107149 107150 107151 107152 107153 107154 107155 107156 107157 107158 107159 107160 107161 107162 107163 107164 107165 107166 107167 107168 107169 107170 107171 107172 107173 107174 107175 107176 107177 107178 107179 107180 107181 107182 107183 107184 107185 107186 107187 107188 107189 107190 107191 107192 107193 107194 107195 107196 107197 107198 107199 107200 107201 107202 107203 107204 107205 107206 107207 107208 107209 107210 107211 107212 107213 107214 107215 107216 107217 107218 107219 107220 107221 107222 107223 107224 107225 107226 107227 107228 107229 107230 107231 107232 107233 107234 107235 107236 107237 107238 107239 107240 107241 107242 107243 107244 107245 107246 107247 107248 107249 107250 107251 107252 107253 107254 107255 107256 107257 107258 107259 107260 107261 107262 107263 107264 107265 107266 107267 107268 107269 107270 107271 107272 107273 107274 107275 107276 107277 107278 107279 107280 107281 107282 107283 107284 107285 107286 107287 107288 107289 107290 107291 107292 107293 107294 107295 107296 107297 107298 107299 107300 |
** yy_action. Used to detect hash collisions.
** yy_shift_ofst[] For each state, the offset into yy_action for
** shifting terminals.
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
#define YY_ACTTAB_COUNT (1564)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 309, 955, 184, 417, 2, 171, 624, 594, 56, 56,
/* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
/* 20 */ 52, 52, 51, 233, 620, 619, 298, 620, 619, 234,
/* 30 */ 587, 581, 56, 56, 56, 56, 19, 54, 54, 54,
/* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 605, 57,
/* 50 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 60 */ 56, 56, 541, 54, 54, 54, 54, 53, 53, 52,
/* 70 */ 52, 52, 51, 233, 309, 594, 325, 196, 195, 194,
/* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 90 */ 51, 233, 617, 616, 165, 617, 616, 380, 377, 376,
/* 100 */ 407, 532, 576, 576, 587, 581, 303, 422, 375, 59,
/* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
/* 120 */ 574, 545, 65, 57, 58, 48, 579, 578, 580, 580,
/* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
/* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 223,
/* 150 */ 539, 420, 170, 176, 138, 280, 383, 275, 382, 168,
/* 160 */ 489, 551, 409, 668, 620, 619, 271, 438, 409, 438,
/* 170 */ 550, 604, 67, 482, 507, 618, 599, 412, 587, 581,
/* 180 */ 600, 483, 618, 412, 618, 598, 91, 439, 440, 439,
/* 190 */ 335, 598, 73, 669, 222, 266, 480, 57, 58, 48,
/* 200 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
/* 210 */ 670, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 220 */ 51, 233, 309, 279, 232, 231, 1, 132, 200, 385,
/* 230 */ 620, 619, 617, 616, 278, 435, 289, 563, 175, 262,
/* 240 */ 409, 264, 437, 497, 436, 166, 441, 568, 336, 568,
/* 250 */ 201, 537, 587, 581, 599, 412, 165, 594, 600, 380,
/* 260 */ 377, 376, 597, 598, 92, 523, 618, 569, 569, 592,
/* 270 */ 375, 57, 58, 48, 579, 578, 580, 580, 55, 55,
/* 280 */ 56, 56, 56, 56, 597, 54, 54, 54, 54, 53,
/* 290 */ 53, 52, 52, 52, 51, 233, 309, 463, 617, 616,
/* 300 */ 590, 590, 590, 174, 272, 396, 409, 272, 409, 548,
/* 310 */ 397, 620, 619, 68, 326, 620, 619, 620, 619, 618,
/* 320 */ 546, 412, 618, 412, 471, 594, 587, 581, 472, 598,
/* 330 */ 92, 598, 92, 52, 52, 52, 51, 233, 513, 512,
/* 340 */ 206, 322, 363, 464, 221, 57, 58, 48, 579, 578,
/* 350 */ 580, 580, 55, 55, 56, 56, 56, 56, 529, 54,
/* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 370 */ 309, 396, 409, 396, 597, 372, 386, 530, 347, 617,
/* 380 */ 616, 575, 202, 617, 616, 617, 616, 412, 620, 619,
/* 390 */ 145, 255, 346, 254, 577, 598, 74, 351, 45, 489,
/* 400 */ 587, 581, 235, 189, 464, 544, 167, 296, 187, 469,
/* 410 */ 479, 67, 62, 39, 618, 546, 597, 345, 573, 57,
/* 420 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
/* 440 */ 52, 52, 51, 233, 309, 562, 558, 407, 528, 576,
/* 450 */ 576, 344, 255, 346, 254, 182, 617, 616, 503, 504,
/* 460 */ 314, 409, 557, 235, 166, 271, 409, 352, 564, 181,
/* 470 */ 407, 546, 576, 576, 587, 581, 412, 537, 556, 561,
/* 480 */ 517, 412, 618, 249, 598, 16, 7, 36, 467, 598,
/* 490 */ 92, 516, 618, 57, 58, 48, 579, 578, 580, 580,
/* 500 */ 55, 55, 56, 56, 56, 56, 541, 54, 54, 54,
/* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 327,
/* 520 */ 572, 571, 525, 558, 560, 394, 871, 246, 409, 248,
/* 530 */ 171, 392, 594, 219, 407, 409, 576, 576, 502, 557,
/* 540 */ 364, 145, 510, 412, 407, 229, 576, 576, 587, 581,
/* 550 */ 412, 598, 92, 381, 269, 556, 166, 400, 598, 69,
/* 560 */ 501, 419, 945, 199, 945, 198, 546, 57, 58, 48,
/* 570 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
/* 580 */ 568, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 590 */ 51, 233, 309, 317, 419, 944, 508, 944, 308, 597,
/* 600 */ 594, 565, 490, 212, 173, 247, 423, 615, 614, 613,
/* 610 */ 323, 197, 143, 405, 572, 571, 489, 66, 50, 47,
/* 620 */ 146, 594, 587, 581, 232, 231, 559, 427, 67, 555,
/* 630 */ 15, 618, 186, 543, 303, 421, 35, 206, 432, 423,
/* 640 */ 552, 57, 58, 48, 579, 578, 580, 580, 55, 55,
/* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
/* 660 */ 53, 52, 52, 52, 51, 233, 309, 569, 569, 260,
/* 670 */ 268, 597, 12, 373, 568, 166, 409, 313, 409, 420,
/* 680 */ 409, 473, 473, 365, 618, 50, 47, 146, 597, 594,
/* 690 */ 468, 412, 166, 412, 351, 412, 587, 581, 32, 598,
/* 700 */ 94, 598, 97, 598, 95, 627, 625, 329, 142, 50,
/* 710 */ 47, 146, 333, 349, 358, 57, 58, 48, 579, 578,
/* 720 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
/* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 740 */ 309, 409, 388, 412, 409, 22, 565, 404, 212, 362,
/* 750 */ 389, 598, 104, 359, 409, 156, 412, 409, 603, 412,
/* 760 */ 537, 331, 569, 569, 598, 103, 493, 598, 105, 412,
/* 770 */ 587, 581, 412, 260, 549, 618, 11, 598, 106, 521,
/* 780 */ 598, 133, 169, 457, 456, 170, 35, 601, 618, 57,
/* 790 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 800 */ 56, 56, 409, 54, 54, 54, 54, 53, 53, 52,
/* 810 */ 52, 52, 51, 233, 309, 409, 259, 412, 409, 50,
/* 820 */ 47, 146, 357, 318, 355, 598, 134, 527, 352, 337,
/* 830 */ 412, 409, 356, 412, 357, 409, 357, 618, 598, 98,
/* 840 */ 129, 598, 102, 618, 587, 581, 412, 21, 235, 618,
/* 850 */ 412, 618, 211, 143, 598, 101, 30, 167, 598, 93,
/* 860 */ 350, 535, 203, 57, 58, 48, 579, 578, 580, 580,
/* 870 */ 55, 55, 56, 56, 56, 56, 409, 54, 54, 54,
/* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 409,
/* 890 */ 526, 412, 409, 425, 215, 305, 597, 551, 141, 598,
/* 900 */ 100, 40, 409, 38, 412, 409, 550, 412, 409, 228,
/* 910 */ 220, 314, 598, 77, 500, 598, 96, 412, 587, 581,
/* 920 */ 412, 338, 253, 412, 218, 598, 137, 379, 598, 136,
/* 930 */ 28, 598, 135, 270, 715, 210, 481, 57, 58, 48,
/* 940 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
/* 950 */ 409, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 960 */ 51, 233, 309, 409, 272, 412, 409, 315, 147, 597,
/* 970 */ 272, 626, 2, 598, 76, 209, 409, 127, 412, 618,
/* 980 */ 126, 412, 409, 621, 235, 618, 598, 90, 374, 598,
/* 990 */ 89, 412, 587, 581, 27, 260, 350, 412, 618, 598,
/* 1000 */ 75, 321, 541, 541, 125, 598, 88, 320, 278, 597,
/* 1010 */ 618, 57, 46, 48, 579, 578, 580, 580, 55, 55,
/* 1020 */ 56, 56, 56, 56, 409, 54, 54, 54, 54, 53,
/* 1030 */ 53, 52, 52, 52, 51, 233, 309, 409, 450, 412,
/* 1040 */ 164, 284, 282, 272, 609, 424, 304, 598, 87, 370,
/* 1050 */ 409, 477, 412, 409, 608, 409, 607, 602, 618, 618,
/* 1060 */ 598, 99, 586, 585, 122, 412, 587, 581, 412, 618,
/* 1070 */ 412, 618, 618, 598, 86, 366, 598, 17, 598, 85,
/* 1080 */ 319, 185, 519, 518, 583, 582, 58, 48, 579, 578,
/* 1090 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
/* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 1110 */ 309, 584, 409, 412, 409, 260, 260, 260, 408, 591,
/* 1120 */ 474, 598, 84, 170, 409, 466, 518, 412, 121, 412,
/* 1130 */ 618, 618, 618, 618, 618, 598, 83, 598, 72, 412,
/* 1140 */ 587, 581, 51, 233, 625, 329, 470, 598, 71, 257,
/* 1150 */ 159, 120, 14, 462, 157, 158, 117, 260, 448, 447,
/* 1160 */ 446, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 1170 */ 56, 56, 618, 54, 54, 54, 54, 53, 53, 52,
/* 1180 */ 52, 52, 51, 233, 44, 403, 260, 3, 409, 459,
/* 1190 */ 260, 413, 619, 118, 398, 10, 25, 24, 554, 348,
/* 1200 */ 217, 618, 406, 412, 409, 618, 4, 44, 403, 618,
/* 1210 */ 3, 598, 82, 618, 413, 619, 455, 542, 115, 412,
/* 1220 */ 538, 401, 536, 274, 506, 406, 251, 598, 81, 216,
/* 1230 */ 273, 563, 618, 243, 453, 618, 154, 618, 618, 618,
/* 1240 */ 449, 416, 623, 110, 401, 618, 409, 236, 64, 123,
/* 1250 */ 487, 41, 42, 531, 563, 204, 409, 267, 43, 411,
/* 1260 */ 410, 412, 265, 592, 108, 618, 107, 434, 332, 598,
/* 1270 */ 80, 412, 618, 263, 41, 42, 443, 618, 409, 598,
/* 1280 */ 70, 43, 411, 410, 433, 261, 592, 149, 618, 597,
/* 1290 */ 256, 237, 188, 412, 590, 590, 590, 589, 588, 13,
/* 1300 */ 618, 598, 18, 328, 235, 618, 44, 403, 360, 3,
/* 1310 */ 418, 461, 339, 413, 619, 227, 124, 590, 590, 590,
/* 1320 */ 589, 588, 13, 618, 406, 409, 618, 409, 139, 34,
/* 1330 */ 403, 387, 3, 148, 622, 312, 413, 619, 311, 330,
/* 1340 */ 412, 460, 412, 401, 180, 353, 412, 406, 598, 79,
/* 1350 */ 598, 78, 250, 563, 598, 9, 618, 612, 611, 610,
/* 1360 */ 618, 8, 452, 442, 242, 415, 401, 618, 239, 235,
/* 1370 */ 179, 238, 428, 41, 42, 288, 563, 618, 618, 618,
/* 1380 */ 43, 411, 410, 618, 144, 592, 618, 618, 177, 61,
/* 1390 */ 618, 596, 391, 620, 619, 287, 41, 42, 414, 618,
/* 1400 */ 293, 30, 393, 43, 411, 410, 292, 618, 592, 31,
/* 1410 */ 618, 395, 291, 60, 230, 37, 590, 590, 590, 589,
/* 1420 */ 588, 13, 214, 553, 183, 290, 172, 301, 300, 299,
/* 1430 */ 178, 297, 595, 563, 451, 29, 285, 390, 540, 590,
/* 1440 */ 590, 590, 589, 588, 13, 283, 520, 534, 150, 533,
/* 1450 */ 241, 281, 384, 192, 191, 324, 515, 514, 276, 240,
/* 1460 */ 510, 523, 307, 511, 128, 592, 509, 225, 226, 486,
/* 1470 */ 485, 224, 152, 491, 464, 306, 484, 163, 153, 371,
/* 1480 */ 478, 151, 162, 258, 369, 161, 367, 208, 475, 476,
/* 1490 */ 26, 160, 465, 140, 361, 131, 590, 590, 590, 116,
/* 1500 */ 119, 454, 343, 155, 114, 342, 113, 112, 445, 111,
/* 1510 */ 130, 109, 431, 316, 426, 430, 23, 429, 20, 606,
/* 1520 */ 190, 507, 255, 341, 244, 63, 294, 593, 310, 570,
/* 1530 */ 277, 402, 354, 235, 567, 496, 495, 492, 494, 302,
/* 1540 */ 458, 378, 286, 245, 566, 5, 252, 547, 193, 444,
/* 1550 */ 233, 340, 207, 524, 368, 505, 334, 522, 499, 399,
/* 1560 */ 295, 498, 956, 488,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
/* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
/* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
/* 30 */ 49, 50, 77, 78, 79, 80, 204, 82, 83, 84,
/* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 23, 68,
/* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 60 */ 79, 80, 166, 82, 83, 84, 85, 86, 87, 88,
/* 70 */ 89, 90, 91, 92, 19, 94, 19, 105, 106, 107,
/* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 90 */ 91, 92, 94, 95, 96, 94, 95, 99, 100, 101,
/* 100 */ 112, 205, 114, 115, 49, 50, 22, 23, 110, 54,
/* 110 */ 86, 87, 88, 89, 90, 91, 92, 221, 222, 223,
/* 120 */ 23, 120, 25, 68, 69, 70, 71, 72, 73, 74,
/* 130 */ 75, 76, 77, 78, 79, 80, 22, 82, 83, 84,
/* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92,
/* 150 */ 23, 67, 25, 96, 97, 98, 99, 100, 101, 102,
/* 160 */ 150, 32, 150, 118, 26, 27, 109, 150, 150, 150,
/* 170 */ 41, 161, 162, 180, 181, 165, 113, 165, 49, 50,
/* 180 */ 117, 188, 165, 165, 165, 173, 174, 170, 171, 170,
/* 190 */ 171, 173, 174, 118, 184, 16, 186, 68, 69, 70,
/* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
/* 210 */ 118, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 220 */ 91, 92, 19, 98, 86, 87, 22, 24, 160, 88,
/* 230 */ 26, 27, 94, 95, 109, 97, 224, 66, 118, 60,
/* 240 */ 150, 62, 104, 23, 106, 25, 229, 230, 229, 230,
/* 250 */ 160, 150, 49, 50, 113, 165, 96, 26, 117, 99,
/* 260 */ 100, 101, 194, 173, 174, 94, 165, 129, 130, 98,
/* 270 */ 110, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86,
/* 290 */ 87, 88, 89, 90, 91, 92, 19, 11, 94, 95,
/* 300 */ 129, 130, 131, 118, 150, 215, 150, 150, 150, 25,
/* 310 */ 220, 26, 27, 22, 213, 26, 27, 26, 27, 165,
/* 320 */ 25, 165, 165, 165, 30, 94, 49, 50, 34, 173,
/* 330 */ 174, 173, 174, 88, 89, 90, 91, 92, 7, 8,
/* 340 */ 160, 187, 48, 57, 187, 68, 69, 70, 71, 72,
/* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 23, 82,
/* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
/* 370 */ 19, 215, 150, 215, 194, 19, 220, 88, 220, 94,
/* 380 */ 95, 23, 160, 94, 95, 94, 95, 165, 26, 27,
/* 390 */ 95, 105, 106, 107, 113, 173, 174, 217, 22, 150,
/* 400 */ 49, 50, 116, 119, 57, 120, 50, 158, 22, 21,
/* 410 */ 161, 162, 232, 136, 165, 120, 194, 237, 23, 68,
/* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 430 */ 79, 80, 22, 82, 83, 84, 85, 86, 87, 88,
/* 440 */ 89, 90, 91, 92, 19, 23, 12, 112, 23, 114,
/* 450 */ 115, 63, 105, 106, 107, 23, 94, 95, 97, 98,
/* 460 */ 104, 150, 28, 116, 25, 109, 150, 150, 23, 23,
/* 470 */ 112, 25, 114, 115, 49, 50, 165, 150, 44, 11,
/* 480 */ 46, 165, 165, 16, 173, 174, 76, 136, 100, 173,
/* 490 */ 174, 57, 165, 68, 69, 70, 71, 72, 73, 74,
/* 500 */ 75, 76, 77, 78, 79, 80, 166, 82, 83, 84,
/* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 169,
/* 520 */ 170, 171, 23, 12, 23, 214, 138, 60, 150, 62,
/* 530 */ 24, 215, 26, 216, 112, 150, 114, 115, 36, 28,
/* 540 */ 213, 95, 103, 165, 112, 205, 114, 115, 49, 50,
/* 550 */ 165, 173, 174, 51, 23, 44, 25, 46, 173, 174,
/* 560 */ 58, 22, 23, 22, 25, 160, 120, 68, 69, 70,
/* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
/* 580 */ 230, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 590 */ 91, 92, 19, 215, 22, 23, 23, 25, 163, 194,
/* 600 */ 94, 166, 167, 168, 25, 138, 67, 7, 8, 9,
/* 610 */ 108, 206, 207, 169, 170, 171, 150, 22, 221, 222,
/* 620 */ 223, 26, 49, 50, 86, 87, 23, 161, 162, 23,
/* 630 */ 22, 165, 24, 120, 22, 23, 25, 160, 241, 67,
/* 640 */ 176, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 650 */ 77, 78, 79, 80, 160, 82, 83, 84, 85, 86,
/* 660 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 150,
/* 670 */ 23, 194, 35, 23, 230, 25, 150, 155, 150, 67,
/* 680 */ 150, 105, 106, 107, 165, 221, 222, 223, 194, 94,
/* 690 */ 23, 165, 25, 165, 217, 165, 49, 50, 25, 173,
/* 700 */ 174, 173, 174, 173, 174, 0, 1, 2, 118, 221,
/* 710 */ 222, 223, 193, 219, 237, 68, 69, 70, 71, 72,
/* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
/* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
/* 740 */ 19, 150, 19, 165, 150, 24, 166, 167, 168, 227,
/* 750 */ 27, 173, 174, 231, 150, 25, 165, 150, 172, 165,
/* 760 */ 150, 242, 129, 130, 173, 174, 180, 173, 174, 165,
/* 770 */ 49, 50, 165, 150, 176, 165, 35, 173, 174, 165,
/* 780 */ 173, 174, 35, 23, 23, 25, 25, 173, 165, 68,
/* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88,
/* 810 */ 89, 90, 91, 92, 19, 150, 193, 165, 150, 221,
/* 820 */ 222, 223, 150, 213, 19, 173, 174, 23, 150, 97,
/* 830 */ 165, 150, 27, 165, 150, 150, 150, 165, 173, 174,
/* 840 */ 22, 173, 174, 165, 49, 50, 165, 52, 116, 165,
/* 850 */ 165, 165, 206, 207, 173, 174, 126, 50, 173, 174,
/* 860 */ 128, 27, 160, 68, 69, 70, 71, 72, 73, 74,
/* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84,
/* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150,
/* 890 */ 23, 165, 150, 23, 216, 25, 194, 32, 39, 173,
/* 900 */ 174, 135, 150, 137, 165, 150, 41, 165, 150, 52,
/* 910 */ 238, 104, 173, 174, 29, 173, 174, 165, 49, 50,
/* 920 */ 165, 219, 238, 165, 238, 173, 174, 52, 173, 174,
/* 930 */ 22, 173, 174, 23, 23, 160, 25, 68, 69, 70,
/* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
/* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 960 */ 91, 92, 19, 150, 150, 165, 150, 245, 246, 194,
/* 970 */ 150, 144, 145, 173, 174, 160, 150, 22, 165, 165,
/* 980 */ 22, 165, 150, 150, 116, 165, 173, 174, 52, 173,
/* 990 */ 174, 165, 49, 50, 22, 150, 128, 165, 165, 173,
/* 1000 */ 174, 187, 166, 166, 22, 173, 174, 187, 109, 194,
/* 1010 */ 165, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86,
/* 1030 */ 87, 88, 89, 90, 91, 92, 19, 150, 193, 165,
/* 1040 */ 102, 205, 205, 150, 150, 247, 248, 173, 174, 19,
/* 1050 */ 150, 20, 165, 150, 150, 150, 150, 150, 165, 165,
/* 1060 */ 173, 174, 49, 50, 104, 165, 49, 50, 165, 165,
/* 1070 */ 165, 165, 165, 173, 174, 43, 173, 174, 173, 174,
/* 1080 */ 187, 24, 190, 191, 71, 72, 69, 70, 71, 72,
/* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
/* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
/* 1110 */ 19, 98, 150, 165, 150, 150, 150, 150, 150, 150,
/* 1120 */ 59, 173, 174, 25, 150, 190, 191, 165, 53, 165,
/* 1130 */ 165, 165, 165, 165, 165, 173, 174, 173, 174, 165,
/* 1140 */ 49, 50, 91, 92, 1, 2, 53, 173, 174, 138,
/* 1150 */ 104, 22, 5, 1, 35, 118, 127, 150, 193, 193,
/* 1160 */ 193, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 1170 */ 79, 80, 165, 82, 83, 84, 85, 86, 87, 88,
/* 1180 */ 89, 90, 91, 92, 19, 20, 150, 22, 150, 27,
/* 1190 */ 150, 26, 27, 108, 150, 22, 76, 76, 150, 25,
/* 1200 */ 193, 165, 37, 165, 150, 165, 22, 19, 20, 165,
/* 1210 */ 22, 173, 174, 165, 26, 27, 23, 150, 119, 165,
/* 1220 */ 150, 56, 150, 150, 150, 37, 16, 173, 174, 193,
/* 1230 */ 150, 66, 165, 193, 1, 165, 121, 165, 165, 165,
/* 1240 */ 20, 146, 147, 119, 56, 165, 150, 152, 16, 154,
/* 1250 */ 150, 86, 87, 88, 66, 160, 150, 150, 93, 94,
/* 1260 */ 95, 165, 150, 98, 108, 165, 127, 23, 65, 173,
/* 1270 */ 174, 165, 165, 150, 86, 87, 128, 165, 150, 173,
/* 1280 */ 174, 93, 94, 95, 23, 150, 98, 15, 165, 194,
/* 1290 */ 150, 140, 22, 165, 129, 130, 131, 132, 133, 134,
/* 1300 */ 165, 173, 174, 3, 116, 165, 19, 20, 150, 22,
/* 1310 */ 4, 150, 217, 26, 27, 179, 179, 129, 130, 131,
/* 1320 */ 132, 133, 134, 165, 37, 150, 165, 150, 164, 19,
/* 1330 */ 20, 150, 22, 246, 149, 249, 26, 27, 249, 244,
/* 1340 */ 165, 150, 165, 56, 6, 150, 165, 37, 173, 174,
/* 1350 */ 173, 174, 150, 66, 173, 174, 165, 149, 149, 13,
/* 1360 */ 165, 25, 150, 150, 150, 149, 56, 165, 150, 116,
/* 1370 */ 151, 150, 150, 86, 87, 150, 66, 165, 165, 165,
/* 1380 */ 93, 94, 95, 165, 150, 98, 165, 165, 151, 22,
/* 1390 */ 165, 194, 150, 26, 27, 150, 86, 87, 159, 165,
/* 1400 */ 199, 126, 123, 93, 94, 95, 200, 165, 98, 124,
/* 1410 */ 165, 122, 201, 125, 225, 135, 129, 130, 131, 132,
/* 1420 */ 133, 134, 5, 157, 157, 202, 118, 10, 11, 12,
/* 1430 */ 13, 14, 203, 66, 17, 104, 210, 121, 211, 129,
/* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
/* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
/* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
/* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
/* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
/* 1490 */ 135, 156, 189, 68, 157, 218, 129, 130, 131, 22,
/* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
/* 1510 */ 218, 189, 40, 157, 38, 157, 240, 157, 240, 153,
/* 1520 */ 196, 181, 105, 106, 107, 243, 198, 166, 111, 230,
/* 1530 */ 176, 226, 239, 116, 230, 176, 166, 166, 176, 148,
/* 1540 */ 199, 177, 209, 209, 166, 196, 239, 208, 185, 199,
/* 1550 */ 92, 209, 233, 173, 234, 182, 139, 173, 182, 191,
/* 1560 */ 195, 182, 250, 186,
};
#define YY_SHIFT_USE_DFLT (-70)
#define YY_SHIFT_COUNT (416)
#define YY_SHIFT_MIN (-69)
#define YY_SHIFT_MAX (1487)
static const short yy_shift_ofst[] = {
/* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
/* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
/* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
/* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 60 */ 1287, 1287, 286, 362, 362, 538, 538, 231, 1253, 55,
/* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869,
/* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
/* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
/* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
/* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
/* 130 */ 732, 868, 231, 1051, 1458, -70, -70, -70, 1367, 57,
/* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
/* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
/* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
/* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
/* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
/* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
/* 230 */ 766, 633, 633, 231, 284, 63, 608, 1476, 1308, 1308,
/* 240 */ 1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
/* 250 */ 1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
/* 260 */ 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
/* 270 */ 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
/* 280 */ 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
/* 290 */ 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
/* 300 */ 1338, 1338, 1338, -70, -70, -70, -70, -70, -70, 1013,
/* 310 */ 467, 612, 84, 179, -28, 870, 410, 761, 760, 667,
/* 320 */ 650, 531, 220, 361, 331, 125, 127, 97, 1306, 1300,
/* 330 */ 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
/* 340 */ 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
/* 350 */ 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
/* 360 */ 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960, 1057,
/* 370 */ 1031, 1030, 899, 938, 982, 936, 972, 958, 910, 955,
/* 380 */ 875, 885, 908, 857, 859, 867, 804, 590, 834, 747,
/* 390 */ 818, 513, 611, 741, 673, 637, 611, 606, 603, 579,
/* 400 */ 501, 541, 468, 386, 445, 395, 376, 281, 185, 120,
/* 410 */ 92, 75, 45, 114, 25, 11, 5,
};
#define YY_REDUCE_USE_DFLT (-169)
#define YY_REDUCE_COUNT (308)
#define YY_REDUCE_MIN (-168)
#define YY_REDUCE_MAX (1391)
static const short yy_reduce_ofst[] = {
/* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
/* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
/* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
/* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
/* 40 */ 800, 758, 755, 752, 742, 739, 726, 685, 681, 668,
/* 50 */ 665, 652, 607, 604, 594, 591, 578, 530, 528, 526,
/* 60 */ 385, 18, 477, 466, 519, 444, 350, 435, 405, 488,
/* 70 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 80 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 90 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 100 */ 488, 488, 488, 488, 488, 488, 488, 1040, 678, 1036,
/* 110 */ 1007, 967, 966, 965, 845, 686, 610, 684, 317, 672,
/* 120 */ 893, 327, 623, 522, -7, 820, 814, 157, 154, 101,
/* 130 */ 702, 494, 580, 488, 488, 488, 488, 488, 614, 586,
/* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
/* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
/* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
/* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
/* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
/* 190 */ -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
/* 200 */ 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
/* 210 */ 1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
/* 220 */ 1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
/* 230 */ 1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
/* 240 */ 1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
/* 250 */ 1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
/* 260 */ 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
/* 270 */ 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
/* 280 */ 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
/* 290 */ 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
/* 300 */ 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
};
static const YYACTIONTYPE yy_default[] = {
/* 0 */ 632, 866, 954, 954, 866, 866, 954, 954, 954, 756,
/* 10 */ 954, 954, 954, 864, 954, 954, 784, 784, 928, 954,
/* 20 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 30 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 40 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 50 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 60 */ 954, 954, 954, 954, 954, 954, 954, 671, 760, 790,
/* 70 */ 954, 954, 954, 954, 954, 954, 954, 954, 927, 929,
/* 80 */ 798, 797, 907, 771, 795, 788, 792, 867, 860, 861,
/* 90 */ 859, 863, 868, 954, 791, 827, 844, 826, 838, 843,
/* 100 */ 850, 842, 839, 829, 828, 830, 831, 954, 954, 954,
/* 110 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 120 */ 954, 954, 954, 658, 725, 954, 954, 954, 954, 954,
/* 130 */ 954, 954, 954, 832, 833, 847, 846, 845, 954, 663,
/* 140 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 150 */ 934, 932, 954, 879, 954, 954, 954, 954, 954, 954,
/* 160 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 170 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 180 */ 638, 756, 756, 756, 632, 954, 954, 954, 946, 760,
/* 190 */ 750, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 200 */ 954, 954, 954, 800, 739, 917, 919, 954, 900, 737,
/* 210 */ 660, 758, 673, 748, 640, 794, 773, 773, 912, 794,
/* 220 */ 912, 696, 719, 954, 784, 954, 784, 693, 784, 773,
/* 230 */ 862, 954, 954, 954, 757, 748, 954, 939, 764, 764,
/* 240 */ 931, 931, 764, 806, 729, 794, 736, 736, 736, 736,
/* 250 */ 764, 655, 794, 806, 729, 729, 764, 655, 906, 904,
/* 260 */ 764, 764, 655, 764, 655, 764, 655, 872, 727, 727,
/* 270 */ 727, 711, 876, 876, 872, 727, 696, 727, 711, 727,
/* 280 */ 727, 777, 772, 777, 772, 777, 772, 764, 764, 954,
/* 290 */ 789, 778, 787, 785, 794, 954, 714, 648, 648, 637,
/* 300 */ 637, 637, 637, 951, 951, 946, 698, 698, 681, 954,
/* 310 */ 954, 954, 954, 954, 954, 954, 881, 954, 954, 954,
/* 320 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 633,
/* 330 */ 941, 954, 954, 938, 954, 954, 954, 954, 799, 954,
/* 340 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 916,
/* 350 */ 954, 954, 954, 954, 954, 954, 954, 910, 954, 954,
/* 360 */ 954, 954, 954, 954, 903, 902, 954, 954, 954, 954,
/* 370 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 380 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 390 */ 954, 954, 786, 954, 779, 954, 865, 954, 954, 954,
/* 400 */ 954, 954, 954, 954, 954, 954, 954, 742, 815, 954,
/* 410 */ 814, 818, 813, 665, 954, 646, 954, 629, 634, 950,
/* 420 */ 953, 952, 949, 948, 947, 942, 940, 937, 936, 935,
/* 430 */ 933, 930, 926, 885, 883, 890, 889, 888, 887, 886,
/* 440 */ 884, 882, 880, 801, 796, 793, 925, 878, 738, 735,
/* 450 */ 734, 654, 943, 909, 918, 805, 804, 807, 915, 914,
/* 460 */ 913, 911, 908, 895, 803, 802, 730, 870, 869, 657,
/* 470 */ 899, 898, 897, 901, 905, 896, 766, 656, 653, 662,
/* 480 */ 717, 718, 726, 724, 723, 722, 721, 720, 716, 664,
/* 490 */ 672, 710, 695, 694, 875, 877, 874, 873, 703, 702,
/* 500 */ 708, 707, 706, 705, 704, 701, 700, 699, 692, 691,
/* 510 */ 697, 690, 713, 712, 709, 689, 733, 732, 731, 728,
/* 520 */ 688, 687, 686, 818, 685, 684, 824, 823, 811, 854,
/* 530 */ 753, 752, 751, 763, 762, 775, 774, 809, 808, 776,
/* 540 */ 761, 755, 754, 770, 769, 768, 767, 759, 749, 781,
/* 550 */ 783, 782, 780, 856, 765, 853, 924, 923, 922, 921,
/* 560 */ 920, 858, 857, 825, 822, 676, 677, 893, 892, 894,
/* 570 */ 891, 679, 678, 675, 674, 855, 744, 743, 851, 848,
/* 580 */ 840, 836, 852, 849, 841, 837, 835, 834, 820, 819,
/* 590 */ 817, 816, 812, 821, 667, 745, 741, 740, 810, 747,
/* 600 */ 746, 683, 682, 680, 661, 659, 652, 650, 649, 651,
/* 610 */ 647, 645, 644, 643, 642, 641, 670, 669, 668, 666,
/* 620 */ 665, 639, 636, 635, 631, 630, 628,
};
/* The next table maps tokens into fallback tokens. If a construct
** like the following:
**
|
| ︙ | ︙ | |||
109093 109094 109095 109096 109097 109098 109099 | "ecmd", "explain", "cmdx", "cmd", "transtype", "trans_opt", "nm", "savepoint_opt", "create_table", "create_table_args", "createkw", "temp", "ifnotexists", "dbnm", "columnlist", "conslist_opt", "select", "column", "columnid", "type", "carglist", "id", "ids", "typetoken", "typename", "signed", "plus_num", "minus_num", | | | | | | 107491 107492 107493 107494 107495 107496 107497 107498 107499 107500 107501 107502 107503 107504 107505 107506 107507 107508 | "ecmd", "explain", "cmdx", "cmd", "transtype", "trans_opt", "nm", "savepoint_opt", "create_table", "create_table_args", "createkw", "temp", "ifnotexists", "dbnm", "columnlist", "conslist_opt", "select", "column", "columnid", "type", "carglist", "id", "ids", "typetoken", "typename", "signed", "plus_num", "minus_num", "ccons", "term", "expr", "onconf", "sortorder", "autoinc", "idxlist_opt", "refargs", "defer_subclause", "refarg", "refact", "init_deferred_pred_opt", "conslist", "tconscomma", "tcons", "idxlist", "defer_subclause_opt", "orconf", "resolvetype", "raisetype", "ifexists", "fullname", "oneselect", "multiselect_op", "distinct", "selcollist", "from", "where_opt", "groupby_opt", "having_opt", "orderby_opt", "limit_opt", "sclp", "as", "seltablist", "stl_prefix", "joinop", "indexed_opt", "on_opt", "using_opt", "joinop2", "inscollist", "sortlist", "nexprlist", |
| ︙ | ︙ | |||
109173 109174 109175 109176 109177 109178 109179 | /* 46 */ "typetoken ::= typename", /* 47 */ "typetoken ::= typename LP signed RP", /* 48 */ "typetoken ::= typename LP signed COMMA signed RP", /* 49 */ "typename ::= ids", /* 50 */ "typename ::= typename ids", /* 51 */ "signed ::= plus_num", /* 52 */ "signed ::= minus_num", | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | > | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 107571 107572 107573 107574 107575 107576 107577 107578 107579 107580 107581 107582 107583 107584 107585 107586 107587 107588 107589 107590 107591 107592 107593 107594 107595 107596 107597 107598 107599 107600 107601 107602 107603 107604 107605 107606 107607 107608 107609 107610 107611 107612 107613 107614 107615 107616 107617 107618 107619 107620 107621 107622 107623 107624 107625 107626 107627 107628 107629 107630 107631 107632 107633 107634 107635 107636 107637 107638 107639 107640 107641 107642 107643 107644 107645 107646 107647 107648 107649 107650 107651 107652 107653 107654 107655 107656 107657 107658 107659 107660 107661 107662 107663 107664 107665 107666 107667 107668 107669 107670 107671 107672 107673 107674 107675 107676 107677 107678 107679 107680 107681 107682 107683 107684 107685 107686 107687 107688 107689 107690 107691 107692 107693 107694 107695 107696 107697 107698 107699 107700 107701 107702 107703 107704 107705 107706 107707 107708 107709 107710 107711 107712 107713 107714 107715 107716 107717 107718 107719 107720 107721 107722 107723 107724 107725 107726 107727 107728 107729 107730 107731 107732 107733 107734 107735 107736 107737 107738 107739 107740 107741 107742 107743 107744 107745 107746 107747 107748 107749 107750 107751 107752 107753 107754 107755 107756 107757 107758 107759 107760 107761 107762 107763 107764 107765 107766 107767 107768 107769 107770 107771 107772 107773 107774 107775 107776 107777 107778 107779 107780 107781 107782 107783 107784 107785 107786 107787 107788 107789 107790 107791 107792 107793 107794 107795 107796 107797 107798 107799 107800 107801 107802 107803 107804 107805 107806 107807 107808 107809 107810 107811 107812 107813 107814 107815 107816 107817 107818 107819 107820 107821 107822 107823 107824 107825 107826 107827 107828 107829 107830 107831 107832 107833 107834 107835 107836 107837 107838 107839 107840 107841 107842 107843 107844 107845 107846 107847 107848 107849 107850 107851 107852 107853 107854 107855 107856 107857 107858 | /* 46 */ "typetoken ::= typename", /* 47 */ "typetoken ::= typename LP signed RP", /* 48 */ "typetoken ::= typename LP signed COMMA signed RP", /* 49 */ "typename ::= ids", /* 50 */ "typename ::= typename ids", /* 51 */ "signed ::= plus_num", /* 52 */ "signed ::= minus_num", /* 53 */ "carglist ::= carglist ccons", /* 54 */ "carglist ::=", /* 55 */ "ccons ::= CONSTRAINT nm", /* 56 */ "ccons ::= DEFAULT term", /* 57 */ "ccons ::= DEFAULT LP expr RP", /* 58 */ "ccons ::= DEFAULT PLUS term", /* 59 */ "ccons ::= DEFAULT MINUS term", /* 60 */ "ccons ::= DEFAULT id", /* 61 */ "ccons ::= NULL onconf", /* 62 */ "ccons ::= NOT NULL onconf", /* 63 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", /* 64 */ "ccons ::= UNIQUE onconf", /* 65 */ "ccons ::= CHECK LP expr RP", /* 66 */ "ccons ::= REFERENCES nm idxlist_opt refargs", /* 67 */ "ccons ::= defer_subclause", /* 68 */ "ccons ::= COLLATE ids", /* 69 */ "autoinc ::=", /* 70 */ "autoinc ::= AUTOINCR", /* 71 */ "refargs ::=", /* 72 */ "refargs ::= refargs refarg", /* 73 */ "refarg ::= MATCH nm", /* 74 */ "refarg ::= ON INSERT refact", /* 75 */ "refarg ::= ON DELETE refact", /* 76 */ "refarg ::= ON UPDATE refact", /* 77 */ "refact ::= SET NULL", /* 78 */ "refact ::= SET DEFAULT", /* 79 */ "refact ::= CASCADE", /* 80 */ "refact ::= RESTRICT", /* 81 */ "refact ::= NO ACTION", /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", /* 84 */ "init_deferred_pred_opt ::=", /* 85 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", /* 86 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", /* 87 */ "conslist_opt ::=", /* 88 */ "conslist_opt ::= COMMA conslist", /* 89 */ "conslist ::= conslist tconscomma tcons", /* 90 */ "conslist ::= tcons", /* 91 */ "tconscomma ::= COMMA", /* 92 */ "tconscomma ::=", /* 93 */ "tcons ::= CONSTRAINT nm", /* 94 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", /* 95 */ "tcons ::= UNIQUE LP idxlist RP onconf", /* 96 */ "tcons ::= CHECK LP expr RP onconf", /* 97 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", /* 98 */ "defer_subclause_opt ::=", /* 99 */ "defer_subclause_opt ::= defer_subclause", /* 100 */ "onconf ::=", /* 101 */ "onconf ::= ON CONFLICT resolvetype", /* 102 */ "orconf ::=", /* 103 */ "orconf ::= OR resolvetype", /* 104 */ "resolvetype ::= raisetype", /* 105 */ "resolvetype ::= IGNORE", /* 106 */ "resolvetype ::= REPLACE", /* 107 */ "cmd ::= DROP TABLE ifexists fullname", /* 108 */ "ifexists ::= IF EXISTS", /* 109 */ "ifexists ::=", /* 110 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select", /* 111 */ "cmd ::= DROP VIEW ifexists fullname", /* 112 */ "cmd ::= select", /* 113 */ "select ::= oneselect", /* 114 */ "select ::= select multiselect_op oneselect", /* 115 */ "multiselect_op ::= UNION", /* 116 */ "multiselect_op ::= UNION ALL", /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT", /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", /* 119 */ "distinct ::= DISTINCT", /* 120 */ "distinct ::= ALL", /* 121 */ "distinct ::=", /* 122 */ "sclp ::= selcollist COMMA", /* 123 */ "sclp ::=", /* 124 */ "selcollist ::= sclp expr as", /* 125 */ "selcollist ::= sclp STAR", /* 126 */ "selcollist ::= sclp nm DOT STAR", /* 127 */ "as ::= AS nm", /* 128 */ "as ::= ids", /* 129 */ "as ::=", /* 130 */ "from ::=", /* 131 */ "from ::= FROM seltablist", /* 132 */ "stl_prefix ::= seltablist joinop", /* 133 */ "stl_prefix ::=", /* 134 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", /* 135 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", /* 136 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", /* 137 */ "dbnm ::=", /* 138 */ "dbnm ::= DOT nm", /* 139 */ "fullname ::= nm dbnm", /* 140 */ "joinop ::= COMMA|JOIN", /* 141 */ "joinop ::= JOIN_KW JOIN", /* 142 */ "joinop ::= JOIN_KW nm JOIN", /* 143 */ "joinop ::= JOIN_KW nm nm JOIN", /* 144 */ "on_opt ::= ON expr", /* 145 */ "on_opt ::=", /* 146 */ "indexed_opt ::=", /* 147 */ "indexed_opt ::= INDEXED BY nm", /* 148 */ "indexed_opt ::= NOT INDEXED", /* 149 */ "using_opt ::= USING LP inscollist RP", /* 150 */ "using_opt ::=", /* 151 */ "orderby_opt ::=", /* 152 */ "orderby_opt ::= ORDER BY sortlist", /* 153 */ "sortlist ::= sortlist COMMA expr sortorder", /* 154 */ "sortlist ::= expr sortorder", /* 155 */ "sortorder ::= ASC", /* 156 */ "sortorder ::= DESC", /* 157 */ "sortorder ::=", /* 158 */ "groupby_opt ::=", /* 159 */ "groupby_opt ::= GROUP BY nexprlist", /* 160 */ "having_opt ::=", /* 161 */ "having_opt ::= HAVING expr", /* 162 */ "limit_opt ::=", /* 163 */ "limit_opt ::= LIMIT expr", /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr", /* 165 */ "limit_opt ::= LIMIT expr COMMA expr", /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt", /* 167 */ "where_opt ::=", /* 168 */ "where_opt ::= WHERE expr", /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt", /* 170 */ "setlist ::= setlist COMMA nm EQ expr", /* 171 */ "setlist ::= nm EQ expr", /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist", /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", /* 175 */ "insert_cmd ::= INSERT orconf", /* 176 */ "insert_cmd ::= REPLACE", /* 177 */ "valuelist ::= VALUES LP nexprlist RP", /* 178 */ "valuelist ::= valuelist COMMA LP exprlist RP", /* 179 */ "inscollist_opt ::=", /* 180 */ "inscollist_opt ::= LP inscollist RP", /* 181 */ "inscollist ::= inscollist COMMA nm", /* 182 */ "inscollist ::= nm", /* 183 */ "expr ::= term", /* 184 */ "expr ::= LP expr RP", /* 185 */ "term ::= NULL", /* 186 */ "expr ::= id", /* 187 */ "expr ::= JOIN_KW", /* 188 */ "expr ::= nm DOT nm", /* 189 */ "expr ::= nm DOT nm DOT nm", /* 190 */ "term ::= INTEGER|FLOAT|BLOB", /* 191 */ "term ::= STRING", /* 192 */ "expr ::= REGISTER", /* 193 */ "expr ::= VARIABLE", /* 194 */ "expr ::= expr COLLATE ids", /* 195 */ "expr ::= CAST LP expr AS typetoken RP", /* 196 */ "expr ::= ID LP distinct exprlist RP", /* 197 */ "expr ::= ID LP STAR RP", /* 198 */ "term ::= CTIME_KW", /* 199 */ "expr ::= expr AND expr", /* 200 */ "expr ::= expr OR expr", /* 201 */ "expr ::= expr LT|GT|GE|LE expr", /* 202 */ "expr ::= expr EQ|NE expr", /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", /* 204 */ "expr ::= expr PLUS|MINUS expr", /* 205 */ "expr ::= expr STAR|SLASH|REM expr", /* 206 */ "expr ::= expr CONCAT expr", /* 207 */ "likeop ::= LIKE_KW", /* 208 */ "likeop ::= NOT LIKE_KW", /* 209 */ "likeop ::= MATCH", /* 210 */ "likeop ::= NOT MATCH", /* 211 */ "expr ::= expr likeop expr", /* 212 */ "expr ::= expr likeop expr ESCAPE expr", /* 213 */ "expr ::= expr ISNULL|NOTNULL", /* 214 */ "expr ::= expr NOT NULL", /* 215 */ "expr ::= expr IS expr", /* 216 */ "expr ::= expr IS NOT expr", /* 217 */ "expr ::= NOT expr", /* 218 */ "expr ::= BITNOT expr", /* 219 */ "expr ::= MINUS expr", /* 220 */ "expr ::= PLUS expr", /* 221 */ "between_op ::= BETWEEN", /* 222 */ "between_op ::= NOT BETWEEN", /* 223 */ "expr ::= expr between_op expr AND expr", /* 224 */ "in_op ::= IN", /* 225 */ "in_op ::= NOT IN", /* 226 */ "expr ::= expr in_op LP exprlist RP", /* 227 */ "expr ::= LP select RP", /* 228 */ "expr ::= expr in_op LP select RP", /* 229 */ "expr ::= expr in_op nm dbnm", /* 230 */ "expr ::= EXISTS LP select RP", /* 231 */ "expr ::= CASE case_operand case_exprlist case_else END", /* 232 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", /* 233 */ "case_exprlist ::= WHEN expr THEN expr", /* 234 */ "case_else ::= ELSE expr", /* 235 */ "case_else ::=", /* 236 */ "case_operand ::= expr", /* 237 */ "case_operand ::=", /* 238 */ "exprlist ::= nexprlist", /* 239 */ "exprlist ::=", /* 240 */ "nexprlist ::= nexprlist COMMA expr", /* 241 */ "nexprlist ::= expr", /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", /* 243 */ "uniqueflag ::= UNIQUE", /* 244 */ "uniqueflag ::=", /* 245 */ "idxlist_opt ::=", /* 246 */ "idxlist_opt ::= LP idxlist RP", /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder", /* 248 */ "idxlist ::= nm collate sortorder", /* 249 */ "collate ::=", /* 250 */ "collate ::= COLLATE ids", /* 251 */ "cmd ::= DROP INDEX ifexists fullname", /* 252 */ "cmd ::= VACUUM", /* 253 */ "cmd ::= VACUUM nm", /* 254 */ "cmd ::= PRAGMA nm dbnm", /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", /* 256 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", /* 257 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", /* 258 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", /* 259 */ "nmnum ::= plus_num", /* 260 */ "nmnum ::= nm", /* 261 */ "nmnum ::= ON", /* 262 */ "nmnum ::= DELETE", /* 263 */ "nmnum ::= DEFAULT", /* 264 */ "plus_num ::= PLUS number", /* 265 */ "plus_num ::= number", /* 266 */ "minus_num ::= MINUS number", /* 267 */ "number ::= INTEGER|FLOAT", /* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", /* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", /* 270 */ "trigger_time ::= BEFORE", /* 271 */ "trigger_time ::= AFTER", /* 272 */ "trigger_time ::= INSTEAD OF", /* 273 */ "trigger_time ::=", /* 274 */ "trigger_event ::= DELETE|INSERT", /* 275 */ "trigger_event ::= UPDATE", /* 276 */ "trigger_event ::= UPDATE OF inscollist", /* 277 */ "foreach_clause ::=", /* 278 */ "foreach_clause ::= FOR EACH ROW", /* 279 */ "when_clause ::=", /* 280 */ "when_clause ::= WHEN expr", /* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI", /* 283 */ "trnm ::= nm", /* 284 */ "trnm ::= nm DOT nm", /* 285 */ "tridxby ::=", /* 286 */ "tridxby ::= INDEXED BY nm", /* 287 */ "tridxby ::= NOT INDEXED", /* 288 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", /* 289 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist", /* 290 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", /* 291 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", /* 292 */ "trigger_cmd ::= select", /* 293 */ "expr ::= RAISE LP IGNORE RP", /* 294 */ "expr ::= RAISE LP raisetype COMMA nm RP", /* 295 */ "raisetype ::= ROLLBACK", /* 296 */ "raisetype ::= ABORT", /* 297 */ "raisetype ::= FAIL", /* 298 */ "cmd ::= DROP TRIGGER ifexists fullname", /* 299 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", /* 300 */ "cmd ::= DETACH database_kw_opt expr", /* 301 */ "key_opt ::=", /* 302 */ "key_opt ::= KEY expr", /* 303 */ "database_kw_opt ::= DATABASE", /* 304 */ "database_kw_opt ::=", /* 305 */ "cmd ::= REINDEX", /* 306 */ "cmd ::= REINDEX nm dbnm", /* 307 */ "cmd ::= ANALYZE", /* 308 */ "cmd ::= ANALYZE nm dbnm", /* 309 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", /* 310 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", /* 311 */ "add_column_fullname ::= fullname", /* 312 */ "kwcolumn_opt ::=", /* 313 */ "kwcolumn_opt ::= COLUMNKW", /* 314 */ "cmd ::= create_vtab", /* 315 */ "cmd ::= create_vtab LP vtabarglist RP", /* 316 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", /* 317 */ "vtabarglist ::= vtabarg", /* 318 */ "vtabarglist ::= vtabarglist COMMA vtabarg", /* 319 */ "vtabarg ::=", /* 320 */ "vtabarg ::= vtabarg vtabargtoken", /* 321 */ "vtabargtoken ::= ANY", /* 322 */ "vtabargtoken ::= lp anylist RP", /* 323 */ "lp ::= LP", /* 324 */ "anylist ::=", /* 325 */ "anylist ::= anylist LP anylist RP", /* 326 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 /* ** Try to increase the size of the parser stack. |
| ︙ | ︙ | |||
109529 109530 109531 109532 109533 109534 109535 |
*/
case 160: /* select */
case 194: /* oneselect */
{
sqlite3SelectDelete(pParse->db, (yypminor->yy159));
}
break;
| | | | | 107929 107930 107931 107932 107933 107934 107935 107936 107937 107938 107939 107940 107941 107942 107943 107944 107945 107946 107947 107948 107949 |
*/
case 160: /* select */
case 194: /* oneselect */
{
sqlite3SelectDelete(pParse->db, (yypminor->yy159));
}
break;
case 173: /* term */
case 174: /* expr */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr);
}
break;
case 178: /* idxlist_opt */
case 187: /* idxlist */
case 197: /* selcollist */
case 200: /* groupby_opt */
case 202: /* orderby_opt */
case 204: /* sclp */
case 214: /* sortlist */
case 215: /* nexprlist */
|
| ︙ | ︙ | |||
109890 109891 109892 109893 109894 109895 109896 |
{ 167, 1 },
{ 167, 4 },
{ 167, 6 },
{ 168, 1 },
{ 168, 2 },
{ 169, 1 },
{ 169, 1 },
| | | < | | | | | | | | | | | | | | | | < < < < < < < < < < > > > > > > > > > > | | | > > | | > | | | 108290 108291 108292 108293 108294 108295 108296 108297 108298 108299 108300 108301 108302 108303 108304 108305 108306 108307 108308 108309 108310 108311 108312 108313 108314 108315 108316 108317 108318 108319 108320 108321 108322 108323 108324 108325 108326 108327 108328 108329 108330 108331 108332 108333 108334 108335 108336 108337 108338 108339 108340 108341 108342 108343 108344 108345 108346 108347 108348 108349 108350 108351 108352 |
{ 167, 1 },
{ 167, 4 },
{ 167, 6 },
{ 168, 1 },
{ 168, 2 },
{ 169, 1 },
{ 169, 1 },
{ 164, 2 },
{ 164, 0 },
{ 172, 2 },
{ 172, 2 },
{ 172, 4 },
{ 172, 3 },
{ 172, 3 },
{ 172, 2 },
{ 172, 2 },
{ 172, 3 },
{ 172, 5 },
{ 172, 2 },
{ 172, 4 },
{ 172, 4 },
{ 172, 1 },
{ 172, 2 },
{ 177, 0 },
{ 177, 1 },
{ 179, 0 },
{ 179, 2 },
{ 181, 2 },
{ 181, 3 },
{ 181, 3 },
{ 181, 3 },
{ 182, 2 },
{ 182, 2 },
{ 182, 1 },
{ 182, 1 },
{ 182, 2 },
{ 180, 3 },
{ 180, 2 },
{ 183, 0 },
{ 183, 2 },
{ 183, 2 },
{ 159, 0 },
{ 159, 2 },
{ 184, 3 },
{ 184, 1 },
{ 185, 1 },
{ 185, 0 },
{ 186, 2 },
{ 186, 7 },
{ 186, 5 },
{ 186, 5 },
{ 186, 10 },
{ 188, 0 },
{ 188, 1 },
{ 175, 0 },
{ 175, 3 },
{ 189, 0 },
{ 189, 2 },
{ 190, 1 },
{ 190, 1 },
{ 190, 1 },
{ 147, 4 },
{ 192, 2 },
|
| ︙ | ︙ | |||
109990 109991 109992 109993 109994 109995 109996 |
{ 209, 2 },
{ 211, 4 },
{ 211, 0 },
{ 202, 0 },
{ 202, 3 },
{ 214, 4 },
{ 214, 2 },
| | | | | 108392 108393 108394 108395 108396 108397 108398 108399 108400 108401 108402 108403 108404 108405 108406 108407 108408 |
{ 209, 2 },
{ 211, 4 },
{ 211, 0 },
{ 202, 0 },
{ 202, 3 },
{ 214, 4 },
{ 214, 2 },
{ 176, 1 },
{ 176, 1 },
{ 176, 0 },
{ 200, 0 },
{ 200, 3 },
{ 201, 0 },
{ 201, 2 },
{ 203, 0 },
{ 203, 2 },
{ 203, 4 },
|
| ︙ | ︙ | |||
110018 110019 110020 110021 110022 110023 110024 |
{ 217, 1 },
{ 219, 4 },
{ 219, 5 },
{ 218, 0 },
{ 218, 3 },
{ 213, 3 },
{ 213, 1 },
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 108420 108421 108422 108423 108424 108425 108426 108427 108428 108429 108430 108431 108432 108433 108434 108435 108436 108437 108438 108439 108440 108441 108442 108443 108444 108445 108446 108447 108448 108449 108450 108451 108452 108453 108454 108455 108456 108457 108458 108459 108460 108461 108462 108463 108464 108465 108466 108467 108468 108469 108470 108471 108472 108473 108474 108475 108476 108477 108478 108479 108480 108481 108482 108483 108484 108485 108486 108487 108488 108489 108490 108491 108492 108493 108494 108495 108496 108497 |
{ 217, 1 },
{ 219, 4 },
{ 219, 5 },
{ 218, 0 },
{ 218, 3 },
{ 213, 3 },
{ 213, 1 },
{ 174, 1 },
{ 174, 3 },
{ 173, 1 },
{ 174, 1 },
{ 174, 1 },
{ 174, 3 },
{ 174, 5 },
{ 173, 1 },
{ 173, 1 },
{ 174, 1 },
{ 174, 1 },
{ 174, 3 },
{ 174, 6 },
{ 174, 5 },
{ 174, 4 },
{ 173, 1 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 221, 1 },
{ 221, 2 },
{ 221, 1 },
{ 221, 2 },
{ 174, 3 },
{ 174, 5 },
{ 174, 2 },
{ 174, 3 },
{ 174, 3 },
{ 174, 4 },
{ 174, 2 },
{ 174, 2 },
{ 174, 2 },
{ 174, 2 },
{ 222, 1 },
{ 222, 2 },
{ 174, 5 },
{ 223, 1 },
{ 223, 2 },
{ 174, 5 },
{ 174, 3 },
{ 174, 5 },
{ 174, 4 },
{ 174, 4 },
{ 174, 5 },
{ 225, 5 },
{ 225, 4 },
{ 226, 2 },
{ 226, 0 },
{ 224, 1 },
{ 224, 0 },
{ 220, 1 },
{ 220, 0 },
{ 215, 3 },
{ 215, 1 },
{ 147, 11 },
{ 227, 1 },
{ 227, 0 },
{ 178, 0 },
{ 178, 3 },
{ 187, 5 },
{ 187, 3 },
{ 228, 0 },
{ 228, 2 },
{ 147, 4 },
{ 147, 1 },
{ 147, 2 },
|
| ︙ | ︙ | |||
110128 110129 110130 110131 110132 110133 110134 |
{ 239, 3 },
{ 239, 2 },
{ 237, 7 },
{ 237, 5 },
{ 237, 5 },
{ 237, 5 },
{ 237, 1 },
| | | | 108530 108531 108532 108533 108534 108535 108536 108537 108538 108539 108540 108541 108542 108543 108544 108545 |
{ 239, 3 },
{ 239, 2 },
{ 237, 7 },
{ 237, 5 },
{ 237, 5 },
{ 237, 5 },
{ 237, 1 },
{ 174, 4 },
{ 174, 6 },
{ 191, 1 },
{ 191, 1 },
{ 191, 1 },
{ 147, 4 },
{ 147, 6 },
{ 147, 3 },
{ 241, 0 },
|
| ︙ | ︙ | |||
110237 110238 110239 110240 110241 110242 110243 |
break;
case 13: /* transtype ::= */
{yygotominor.yy392 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
| | | | 108639 108640 108641 108642 108643 108644 108645 108646 108647 108648 108649 108650 108651 108652 108653 108654 |
break;
case 13: /* transtype ::= */
{yygotominor.yy392 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
{yygotominor.yy392 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
{sqlite3CommitTransaction(pParse);}
break;
case 19: /* cmd ::= ROLLBACK trans_opt */
|
| ︙ | ︙ | |||
110276 110277 110278 110279 110280 110281 110282 |
{
pParse->db->lookaside.bEnabled = 0;
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
| | | | | | | | | | | | | | | | | | 108678 108679 108680 108681 108682 108683 108684 108685 108686 108687 108688 108689 108690 108691 108692 108693 108694 108695 108696 108697 108698 108699 108700 108701 108702 108703 108704 108705 108706 108707 108708 108709 108710 108711 |
{
pParse->db->lookaside.bEnabled = 0;
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
case 69: /* autoinc ::= */ yytestcase(yyruleno==69);
case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
case 121: /* distinct ::= */ yytestcase(yyruleno==121);
case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
{yygotominor.yy392 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
{yygotominor.yy392 = 1;}
break;
case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
{
sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
}
break;
|
| ︙ | ︙ | |||
110319 110320 110321 110322 110323 110324 110325 110326 110327 110328 110329 110330 110331 110332 110333 110334 110335 |
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
case 37: /* columnid ::= nm */
{
sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 38: /* id ::= ID */
case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
case 41: /* nm ::= id */ yytestcase(yyruleno==41);
case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
| > | | | | | | | | | | | | | | | | > < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 108721 108722 108723 108724 108725 108726 108727 108728 108729 108730 108731 108732 108733 108734 108735 108736 108737 108738 108739 108740 108741 108742 108743 108744 108745 108746 108747 108748 108749 108750 108751 108752 108753 108754 108755 108756 108757 108758 108759 108760 108761 108762 108763 108764 108765 108766 108767 108768 108769 108770 108771 108772 108773 108774 108775 108776 108777 108778 108779 108780 108781 108782 108783 108784 108785 108786 108787 108788 108789 108790 108791 108792 108793 108794 108795 108796 108797 108798 108799 108800 108801 108802 108803 108804 108805 108806 108807 108808 108809 108810 108811 108812 108813 108814 108815 108816 108817 108818 108819 108820 108821 108822 108823 108824 108825 108826 108827 108828 108829 108830 108831 108832 108833 108834 108835 108836 108837 108838 108839 108840 108841 108842 108843 108844 108845 108846 108847 108848 108849 108850 108851 108852 108853 108854 108855 108856 108857 108858 108859 108860 108861 108862 108863 108864 108865 108866 108867 108868 108869 108870 108871 108872 108873 108874 108875 108876 108877 108878 108879 108880 108881 108882 108883 108884 108885 108886 108887 108888 108889 108890 108891 108892 108893 108894 108895 108896 108897 108898 108899 108900 108901 108902 108903 108904 108905 108906 108907 108908 108909 108910 108911 108912 108913 108914 108915 108916 108917 108918 108919 108920 108921 108922 108923 108924 108925 108926 108927 108928 108929 108930 108931 108932 108933 108934 108935 108936 108937 108938 108939 108940 108941 108942 108943 108944 108945 108946 108947 108948 108949 108950 108951 108952 108953 108954 108955 108956 108957 108958 108959 108960 108961 108962 108963 108964 108965 108966 108967 108968 108969 108970 108971 108972 108973 108974 108975 108976 108977 108978 108979 108980 108981 108982 108983 108984 108985 108986 108987 108988 108989 108990 108991 108992 108993 108994 108995 108996 108997 108998 108999 109000 109001 109002 109003 109004 109005 109006 109007 109008 109009 109010 109011 109012 109013 109014 109015 109016 109017 109018 109019 109020 109021 109022 109023 109024 109025 109026 109027 109028 109029 109030 109031 109032 109033 109034 109035 109036 109037 109038 109039 109040 109041 109042 109043 109044 109045 109046 109047 109048 109049 109050 109051 109052 109053 109054 109055 109056 109057 109058 109059 109060 109061 109062 109063 109064 109065 109066 109067 109068 109069 109070 109071 109072 109073 109074 109075 109076 109077 109078 109079 109080 109081 109082 109083 109084 109085 109086 109087 109088 109089 109090 109091 109092 109093 109094 109095 109096 109097 109098 109099 109100 109101 109102 109103 109104 109105 109106 109107 109108 109109 109110 109111 109112 109113 109114 109115 109116 109117 109118 109119 109120 109121 109122 109123 109124 109125 109126 109127 109128 109129 109130 109131 109132 109133 109134 109135 109136 109137 109138 109139 109140 109141 109142 109143 109144 109145 109146 109147 109148 109149 109150 109151 109152 109153 109154 109155 109156 109157 109158 109159 109160 109161 109162 109163 109164 109165 109166 109167 109168 109169 109170 109171 109172 109173 109174 109175 109176 109177 109178 109179 109180 109181 109182 109183 109184 109185 109186 109187 109188 109189 109190 109191 109192 109193 109194 109195 109196 109197 109198 109199 109200 109201 109202 109203 109204 109205 109206 109207 109208 109209 109210 109211 109212 109213 109214 109215 109216 109217 109218 109219 109220 109221 109222 109223 109224 109225 109226 109227 109228 109229 109230 109231 109232 109233 109234 109235 109236 109237 109238 109239 109240 109241 109242 109243 109244 109245 109246 109247 109248 109249 109250 109251 109252 109253 109254 109255 109256 109257 109258 109259 109260 109261 109262 109263 109264 109265 109266 109267 109268 109269 109270 109271 109272 109273 109274 109275 109276 109277 109278 109279 109280 109281 109282 109283 109284 109285 109286 109287 109288 109289 109290 109291 109292 109293 109294 109295 109296 109297 109298 109299 109300 109301 109302 109303 109304 109305 109306 109307 109308 109309 109310 109311 109312 109313 109314 109315 109316 109317 109318 109319 109320 109321 109322 109323 109324 109325 109326 109327 109328 109329 109330 109331 109332 109333 109334 109335 109336 109337 109338 109339 109340 109341 109342 109343 109344 109345 109346 109347 109348 109349 109350 109351 109352 109353 109354 109355 109356 109357 109358 109359 109360 109361 109362 109363 109364 |
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
case 37: /* columnid ::= nm */
{
sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
pParse->constraintName.n = 0;
}
break;
case 38: /* id ::= ID */
case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
case 41: /* nm ::= id */ yytestcase(yyruleno==41);
case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
case 127: /* as ::= AS nm */ yytestcase(yyruleno==127);
case 128: /* as ::= ids */ yytestcase(yyruleno==128);
case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138);
case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147);
case 250: /* collate ::= COLLATE ids */ yytestcase(yyruleno==250);
case 259: /* nmnum ::= plus_num */ yytestcase(yyruleno==259);
case 260: /* nmnum ::= nm */ yytestcase(yyruleno==260);
case 261: /* nmnum ::= ON */ yytestcase(yyruleno==261);
case 262: /* nmnum ::= DELETE */ yytestcase(yyruleno==262);
case 263: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==263);
case 264: /* plus_num ::= PLUS number */ yytestcase(yyruleno==264);
case 265: /* plus_num ::= number */ yytestcase(yyruleno==265);
case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266);
case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267);
case 283: /* trnm ::= nm */ yytestcase(yyruleno==283);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
case 45: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
case 47: /* typetoken ::= typename LP signed RP */
{
yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
case 48: /* typetoken ::= typename LP signed COMMA signed RP */
{
yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
case 50: /* typename ::= typename ids */
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
case 55: /* ccons ::= CONSTRAINT nm */
case 93: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
case 56: /* ccons ::= DEFAULT term */
case 58: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==58);
{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);}
break;
case 57: /* ccons ::= DEFAULT LP expr RP */
{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);}
break;
case 59: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0);
v.zStart = yymsp[-1].minor.yy0.z;
v.zEnd = yymsp[0].minor.yy342.zEnd;
sqlite3AddDefaultValue(pParse,&v);
}
break;
case 60: /* ccons ::= DEFAULT id */
{
ExprSpan v;
spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
sqlite3AddDefaultValue(pParse,&v);
}
break;
case 62: /* ccons ::= NOT NULL onconf */
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);}
break;
case 63: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
break;
case 64: /* ccons ::= UNIQUE onconf */
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
break;
case 65: /* ccons ::= CHECK LP expr RP */
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);}
break;
case 66: /* ccons ::= REFERENCES nm idxlist_opt refargs */
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);}
break;
case 67: /* ccons ::= defer_subclause */
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
break;
case 68: /* ccons ::= COLLATE ids */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
case 71: /* refargs ::= */
{ yygotominor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
case 72: /* refargs ::= refargs refarg */
{ yygotominor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
break;
case 73: /* refarg ::= MATCH nm */
case 74: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==74);
{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; }
break;
case 75: /* refarg ::= ON DELETE refact */
{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; }
break;
case 76: /* refarg ::= ON UPDATE refact */
{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; }
break;
case 77: /* refact ::= SET NULL */
{ yygotominor.yy392 = OE_SetNull; /* EV: R-33326-45252 */}
break;
case 78: /* refact ::= SET DEFAULT */
{ yygotominor.yy392 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
case 79: /* refact ::= CASCADE */
{ yygotominor.yy392 = OE_Cascade; /* EV: R-33326-45252 */}
break;
case 80: /* refact ::= RESTRICT */
{ yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */}
break;
case 81: /* refact ::= NO ACTION */
{ yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */}
break;
case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99);
case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101);
case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104);
{yygotominor.yy392 = yymsp[0].minor.yy392;}
break;
case 87: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
case 88: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
case 91: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);}
break;
case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);}
break;
case 96: /* tcons ::= CHECK LP expr RP onconf */
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);}
break;
case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
{
sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392);
sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392);
}
break;
case 100: /* onconf ::= */
{yygotominor.yy392 = OE_Default;}
break;
case 102: /* orconf ::= */
{yygotominor.yy258 = OE_Default;}
break;
case 103: /* orconf ::= OR resolvetype */
{yygotominor.yy258 = (u8)yymsp[0].minor.yy392;}
break;
case 105: /* resolvetype ::= IGNORE */
{yygotominor.yy392 = OE_Ignore;}
break;
case 106: /* resolvetype ::= REPLACE */
{yygotominor.yy392 = OE_Replace;}
break;
case 107: /* cmd ::= DROP TABLE ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
}
break;
case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
{
sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392);
}
break;
case 111: /* cmd ::= DROP VIEW ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
}
break;
case 112: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
sqlite3Select(pParse, yymsp[0].minor.yy159, &dest);
sqlite3ExplainBegin(pParse->pVdbe);
sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy159);
sqlite3ExplainFinish(pParse->pVdbe);
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
}
break;
case 113: /* select ::= oneselect */
{yygotominor.yy159 = yymsp[0].minor.yy159;}
break;
case 114: /* select ::= select multiselect_op oneselect */
{
if( yymsp[0].minor.yy159 ){
yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
}else{
sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
}
yygotominor.yy159 = yymsp[0].minor.yy159;
}
break;
case 116: /* multiselect_op ::= UNION ALL */
{yygotominor.yy392 = TK_ALL;}
break;
case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
}
break;
case 122: /* sclp ::= selcollist COMMA */
case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
{yygotominor.yy442 = yymsp[-1].minor.yy442;}
break;
case 123: /* sclp ::= */
case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151);
case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158);
case 239: /* exprlist ::= */ yytestcase(yyruleno==239);
case 245: /* idxlist_opt ::= */ yytestcase(yyruleno==245);
{yygotominor.yy442 = 0;}
break;
case 124: /* selcollist ::= sclp expr as */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr);
if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[0].minor.yy0, 1);
sqlite3ExprListSetSpan(pParse,yygotominor.yy442,&yymsp[-1].minor.yy342);
}
break;
case 125: /* selcollist ::= sclp STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p);
}
break;
case 126: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot);
}
break;
case 129: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
case 130: /* from ::= */
{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));}
break;
case 131: /* from ::= FROM seltablist */
{
yygotominor.yy347 = yymsp[0].minor.yy347;
sqlite3SrcListShiftJoinType(yygotominor.yy347);
}
break;
case 132: /* stl_prefix ::= seltablist joinop */
{
yygotominor.yy347 = yymsp[-1].minor.yy347;
if( ALWAYS(yygotominor.yy347 && yygotominor.yy347->nSrc>0) ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392;
}
break;
case 133: /* stl_prefix ::= */
{yygotominor.yy347 = 0;}
break;
case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0);
}
break;
case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
}
break;
case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
yygotominor.yy347 = yymsp[-4].minor.yy347;
}else{
Select *pSubquery;
sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
}
}
break;
case 137: /* dbnm ::= */
case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
case 139: /* fullname ::= nm dbnm */
{yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 140: /* joinop ::= COMMA|JOIN */
{ yygotominor.yy392 = JT_INNER; }
break;
case 141: /* joinop ::= JOIN_KW JOIN */
{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
break;
case 142: /* joinop ::= JOIN_KW nm JOIN */
{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
break;
case 143: /* joinop ::= JOIN_KW nm nm JOIN */
{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
break;
case 144: /* on_opt ::= ON expr */
case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161);
case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168);
case 234: /* case_else ::= ELSE expr */ yytestcase(yyruleno==234);
case 236: /* case_operand ::= expr */ yytestcase(yyruleno==236);
{yygotominor.yy122 = yymsp[0].minor.yy342.pExpr;}
break;
case 145: /* on_opt ::= */
case 160: /* having_opt ::= */ yytestcase(yyruleno==160);
case 167: /* where_opt ::= */ yytestcase(yyruleno==167);
case 235: /* case_else ::= */ yytestcase(yyruleno==235);
case 237: /* case_operand ::= */ yytestcase(yyruleno==237);
{yygotominor.yy122 = 0;}
break;
case 148: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
case 149: /* using_opt ::= USING LP inscollist RP */
case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180);
{yygotominor.yy180 = yymsp[-1].minor.yy180;}
break;
case 150: /* using_opt ::= */
case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
{yygotominor.yy180 = 0;}
break;
case 152: /* orderby_opt ::= ORDER BY sortlist */
case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159);
case 238: /* exprlist ::= nexprlist */ yytestcase(yyruleno==238);
{yygotominor.yy442 = yymsp[0].minor.yy442;}
break;
case 153: /* sortlist ::= sortlist COMMA expr sortorder */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr);
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 154: /* sortlist ::= expr sortorder */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr);
if( yygotominor.yy442 && ALWAYS(yygotominor.yy442->a) ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 155: /* sortorder ::= ASC */
case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
{yygotominor.yy392 = SQLITE_SO_ASC;}
break;
case 156: /* sortorder ::= DESC */
{yygotominor.yy392 = SQLITE_SO_DESC;}
break;
case 162: /* limit_opt ::= */
{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;}
break;
case 163: /* limit_opt ::= LIMIT expr */
{yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;}
break;
case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
{yygotominor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;}
break;
case 165: /* limit_opt ::= LIMIT expr COMMA expr */
{yygotominor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;}
break;
case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
{
sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0);
sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122);
}
break;
case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
{
sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0);
sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list");
sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy258);
}
break;
case 170: /* setlist ::= setlist COMMA nm EQ expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr);
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
}
break;
case 171: /* setlist ::= nm EQ expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr);
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
}
break;
case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
{sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
break;
case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
{sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
break;
case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
{sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy258);}
break;
case 175: /* insert_cmd ::= INSERT orconf */
{yygotominor.yy258 = yymsp[0].minor.yy258;}
break;
case 176: /* insert_cmd ::= REPLACE */
{yygotominor.yy258 = OE_Replace;}
break;
case 177: /* valuelist ::= VALUES LP nexprlist RP */
{
yygotominor.yy487.pList = yymsp[-1].minor.yy442;
yygotominor.yy487.pSelect = 0;
}
break;
case 178: /* valuelist ::= valuelist COMMA LP exprlist RP */
{
Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy442, 0, 0, 0, 0, 0, 0, 0, 0);
if( yymsp[-4].minor.yy487.pList ){
yymsp[-4].minor.yy487.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy487.pList, 0, 0, 0, 0, 0, 0, 0, 0);
yymsp[-4].minor.yy487.pList = 0;
}
yygotominor.yy487.pList = 0;
if( yymsp[-4].minor.yy487.pSelect==0 || pRight==0 ){
sqlite3SelectDelete(pParse->db, pRight);
sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy487.pSelect);
yygotominor.yy487.pSelect = 0;
}else{
pRight->op = TK_ALL;
pRight->pPrior = yymsp[-4].minor.yy487.pSelect;
pRight->selFlags |= SF_Values;
pRight->pPrior->selFlags |= SF_Values;
yygotominor.yy487.pSelect = pRight;
}
}
break;
case 181: /* inscollist ::= inscollist COMMA nm */
{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
break;
case 182: /* inscollist ::= nm */
{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
case 183: /* expr ::= term */
{yygotominor.yy342 = yymsp[0].minor.yy342;}
break;
case 184: /* expr ::= LP expr RP */
{yygotominor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr; spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 185: /* term ::= NULL */
case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
{spanExpr(&yygotominor.yy342, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
case 186: /* expr ::= id */
case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
{spanExpr(&yygotominor.yy342, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
case 188: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 189: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 192: /* expr ::= REGISTER */
{
/* 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. */
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
yygotominor.yy342.pExpr = 0;
}else{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
if( yygotominor.yy342.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy342.pExpr->iTable);
}
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 193: /* expr ::= VARIABLE */
{
spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr);
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 194: /* expr ::= expr COLLATE ids */
{
yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 195: /* expr ::= CAST LP expr AS typetoken RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0);
spanSet(&yygotominor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 196: /* expr ::= ID LP distinct exprlist RP */
{
if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->flags |= EP_Distinct;
}
}
break;
case 197: /* expr ::= ID LP STAR RP */
{
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 198: /* term ::= CTIME_KW */
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->op = TK_CONST_FUNC;
}
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 199: /* expr ::= expr AND expr */
case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
{spanBinaryExpr(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);}
break;
case 207: /* likeop ::= LIKE_KW */
case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 0;}
break;
case 208: /* likeop ::= NOT LIKE_KW */
case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210);
{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 1;}
break;
case 211: /* expr ::= expr likeop expr */
{
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr);
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator);
if( yymsp[-1].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
}
break;
case 212: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator);
if( yymsp[-3].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
}
break;
case 213: /* expr ::= expr ISNULL|NOTNULL */
{spanUnaryPostfix(&yygotominor.yy342,pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);}
break;
case 214: /* expr ::= expr NOT NULL */
{spanUnaryPostfix(&yygotominor.yy342,pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);}
break;
case 215: /* expr ::= expr IS expr */
{
spanBinaryExpr(&yygotominor.yy342,pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_ISNULL);
}
break;
case 216: /* expr ::= expr IS NOT expr */
{
spanBinaryExpr(&yygotominor.yy342,pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_NOTNULL);
}
break;
case 217: /* expr ::= NOT expr */
case 218: /* expr ::= BITNOT expr */ yytestcase(yyruleno==218);
{spanUnaryPrefix(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
break;
case 219: /* expr ::= MINUS expr */
{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
break;
case 220: /* expr ::= PLUS expr */
{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
break;
case 223: /* expr ::= expr between_op expr AND expr */
{
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
}
break;
case 226: /* expr ::= expr in_op LP exprlist RP */
{
if( yymsp[-1].minor.yy442==0 ){
/* Expressions of the form
**
** expr1 IN ()
** expr1 NOT IN ()
**
|
| ︙ | ︙ | |||
110973 110974 110975 110976 110977 110978 110979 |
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
}
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | 109377 109378 109379 109380 109381 109382 109383 109384 109385 109386 109387 109388 109389 109390 109391 109392 109393 109394 109395 109396 109397 109398 109399 109400 109401 109402 109403 109404 109405 109406 109407 109408 109409 109410 109411 109412 109413 109414 109415 109416 109417 109418 109419 109420 109421 109422 109423 109424 109425 109426 109427 109428 109429 109430 109431 109432 109433 109434 109435 109436 109437 109438 109439 109440 109441 109442 109443 109444 109445 109446 109447 109448 109449 109450 109451 109452 109453 109454 109455 109456 109457 109458 109459 109460 109461 109462 109463 109464 109465 109466 109467 109468 109469 109470 109471 109472 109473 109474 109475 109476 109477 109478 109479 109480 109481 109482 109483 109484 109485 109486 109487 109488 109489 109490 109491 109492 109493 109494 109495 109496 109497 109498 109499 109500 109501 109502 109503 109504 109505 109506 109507 109508 109509 109510 109511 109512 109513 109514 109515 109516 109517 109518 109519 109520 109521 109522 109523 109524 109525 109526 109527 109528 109529 109530 109531 109532 109533 109534 109535 109536 109537 109538 109539 109540 109541 109542 109543 109544 109545 109546 109547 109548 109549 109550 109551 109552 109553 109554 109555 109556 109557 109558 109559 109560 109561 109562 109563 109564 109565 109566 109567 109568 109569 109570 109571 109572 109573 109574 109575 109576 109577 109578 109579 109580 109581 109582 109583 109584 109585 109586 109587 109588 109589 109590 109591 109592 109593 109594 109595 109596 109597 109598 109599 109600 109601 109602 109603 109604 109605 109606 109607 109608 109609 109610 109611 109612 109613 109614 109615 109616 109617 109618 109619 109620 109621 109622 109623 109624 109625 109626 109627 109628 109629 109630 109631 109632 109633 109634 109635 109636 109637 109638 109639 109640 109641 109642 109643 109644 109645 109646 109647 109648 109649 109650 109651 109652 109653 109654 109655 109656 109657 109658 109659 109660 109661 109662 109663 109664 109665 109666 109667 109668 109669 109670 109671 109672 109673 109674 109675 109676 109677 109678 109679 109680 109681 109682 109683 109684 109685 109686 109687 109688 109689 109690 109691 109692 109693 109694 109695 109696 109697 109698 109699 109700 109701 109702 109703 109704 109705 109706 109707 109708 109709 109710 109711 109712 109713 109714 109715 109716 109717 109718 109719 109720 109721 109722 109723 109724 109725 109726 109727 109728 109729 109730 109731 109732 109733 109734 109735 109736 109737 109738 109739 109740 109741 109742 109743 109744 109745 109746 109747 109748 109749 109750 109751 109752 109753 109754 109755 109756 109757 109758 109759 109760 |
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
}
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 227: /* expr ::= LP select RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
}
yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 228: /* expr ::= expr in_op LP select RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 229: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
if( yymsp[-2].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-3].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
case 230: /* expr ::= EXISTS LP select RP */
{
Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = yymsp[-1].minor.yy159;
ExprSetProperty(p, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
}
yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 231: /* expr ::= CASE case_operand case_exprlist case_else END */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pList = yymsp[-2].minor.yy442;
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
}
yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr);
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
}
break;
case 233: /* case_exprlist ::= WHEN expr THEN expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
}
break;
case 240: /* nexprlist ::= nexprlist COMMA expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
break;
case 241: /* nexprlist ::= expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
break;
case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
{
sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
&yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
}
break;
case 243: /* uniqueflag ::= UNIQUE */
case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
{yygotominor.yy392 = OE_Abort;}
break;
case 244: /* uniqueflag ::= */
{yygotominor.yy392 = OE_None;}
break;
case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
}
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 248: /* idxlist ::= nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
}
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 249: /* collate ::= */
{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
break;
case 251: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);}
break;
case 252: /* cmd ::= VACUUM */
case 253: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==253);
{sqlite3Vacuum(pParse);}
break;
case 254: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
case 255: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
case 256: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
case 257: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
case 258: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
case 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy327, &all);
}
break;
case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
case 270: /* trigger_time ::= BEFORE */
case 273: /* trigger_time ::= */ yytestcase(yyruleno==273);
{ yygotominor.yy392 = TK_BEFORE; }
break;
case 271: /* trigger_time ::= AFTER */
{ yygotominor.yy392 = TK_AFTER; }
break;
case 272: /* trigger_time ::= INSTEAD OF */
{ yygotominor.yy392 = TK_INSTEAD;}
break;
case 274: /* trigger_event ::= DELETE|INSERT */
case 275: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==275);
{yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;}
break;
case 276: /* trigger_event ::= UPDATE OF inscollist */
{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;}
break;
case 279: /* when_clause ::= */
case 301: /* key_opt ::= */ yytestcase(yyruleno==301);
{ yygotominor.yy122 = 0; }
break;
case 280: /* when_clause ::= WHEN expr */
case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302);
{ yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; }
break;
case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
assert( yymsp[-2].minor.yy327!=0 );
yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327;
yygotominor.yy327 = yymsp[-2].minor.yy327;
}
break;
case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
assert( yymsp[-1].minor.yy327!=0 );
yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327;
yygotominor.yy327 = yymsp[-1].minor.yy327;
}
break;
case 284: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
"statements within triggers");
}
break;
case 286: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 287: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 288: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
{ yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy258); }
break;
case 289: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-4].minor.yy258);}
break;
case 290: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy258);}
break;
case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);}
break;
case 292: /* trigger_cmd ::= select */
{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); }
break;
case 293: /* expr ::= RAISE LP IGNORE RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->affinity = OE_Ignore;
}
yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
if( yygotominor.yy342.pExpr ) {
yygotominor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392;
}
yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 295: /* raisetype ::= ROLLBACK */
{yygotominor.yy392 = OE_Rollback;}
break;
case 297: /* raisetype ::= FAIL */
{yygotominor.yy392 = OE_Fail;}
break;
case 298: /* cmd ::= DROP TRIGGER ifexists fullname */
{
sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
}
break;
case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122);
}
break;
case 300: /* cmd ::= DETACH database_kw_opt expr */
{
sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr);
}
break;
case 305: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
case 306: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 307: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
case 308: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 309: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
}
break;
case 310: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
case 311: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
}
break;
case 314: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
case 315: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
case 316: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy392);
}
break;
case 319: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
case 321: /* vtabargtoken ::= ANY */
case 322: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==322);
case 323: /* lp ::= LP */ yytestcase(yyruleno==323);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
default:
/* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
/* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
/* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
/* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
/* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
/* (10) trans_opt ::= */ yytestcase(yyruleno==10);
/* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
/* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
/* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
/* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
/* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
/* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
/* (35) columnlist ::= column */ yytestcase(yyruleno==35);
/* (44) type ::= */ yytestcase(yyruleno==44);
/* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
/* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
/* (53) carglist ::= carglist ccons */ yytestcase(yyruleno==53);
/* (54) carglist ::= */ yytestcase(yyruleno==54);
/* (61) ccons ::= NULL onconf */ yytestcase(yyruleno==61);
/* (89) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==89);
/* (90) conslist ::= tcons */ yytestcase(yyruleno==90);
/* (92) tconscomma ::= */ yytestcase(yyruleno==92);
/* (277) foreach_clause ::= */ yytestcase(yyruleno==277);
/* (278) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==278);
/* (285) tridxby ::= */ yytestcase(yyruleno==285);
/* (303) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==303);
/* (304) database_kw_opt ::= */ yytestcase(yyruleno==304);
/* (312) kwcolumn_opt ::= */ yytestcase(yyruleno==312);
/* (313) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==313);
/* (317) vtabarglist ::= vtabarg */ yytestcase(yyruleno==317);
/* (318) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==318);
/* (320) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==320);
/* (324) anylist ::= */ yytestcase(yyruleno==324);
/* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325);
/* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326);
break;
};
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
yypParser->yyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
if( yyact < YYNSTATE ){
|
| ︙ | ︙ | |||
112851 112852 112853 112854 112855 112856 112857 112858 112859 112860 112861 112862 112863 112864 | ** name of a directory, then that directory will be used to store ** temporary files. ** ** See also the "PRAGMA temp_store_directory" SQL command. */ SQLITE_API char *sqlite3_temp_directory = 0; /* ** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as | > > > > > > > > > | 111256 111257 111258 111259 111260 111261 111262 111263 111264 111265 111266 111267 111268 111269 111270 111271 111272 111273 111274 111275 111276 111277 111278 | ** name of a directory, then that directory will be used to store ** temporary files. ** ** See also the "PRAGMA temp_store_directory" SQL command. */ SQLITE_API char *sqlite3_temp_directory = 0; /* ** If the following global variable points to a string which is the ** name of a directory, then that directory will be used to store ** all database files specified with a relative pathname. ** ** See also the "PRAGMA data_store_directory" SQL command. */ SQLITE_API char *sqlite3_data_directory = 0; /* ** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as |
| ︙ | ︙ | |||
113049 113050 113051 113052 113053 113054 113055 113056 113057 113058 113059 113060 113061 113062 |
if( sqlite3GlobalConfig.isPCacheInit ){
sqlite3PcacheShutdown();
sqlite3GlobalConfig.isPCacheInit = 0;
}
if( sqlite3GlobalConfig.isMallocInit ){
sqlite3MallocEnd();
sqlite3GlobalConfig.isMallocInit = 0;
}
if( sqlite3GlobalConfig.isMutexInit ){
sqlite3MutexEnd();
sqlite3GlobalConfig.isMutexInit = 0;
}
return SQLITE_OK;
| > > > > > > > > > > > > | 111463 111464 111465 111466 111467 111468 111469 111470 111471 111472 111473 111474 111475 111476 111477 111478 111479 111480 111481 111482 111483 111484 111485 111486 111487 111488 |
if( sqlite3GlobalConfig.isPCacheInit ){
sqlite3PcacheShutdown();
sqlite3GlobalConfig.isPCacheInit = 0;
}
if( sqlite3GlobalConfig.isMallocInit ){
sqlite3MallocEnd();
sqlite3GlobalConfig.isMallocInit = 0;
#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES
/* The heap subsystem has now been shutdown and these values are supposed
** to be NULL or point to memory that was obtained from sqlite3_malloc(),
** which would rely on that heap subsystem; therefore, make sure these
** values cannot refer to heap memory that was just invalidated when the
** heap subsystem was shutdown. This is only done if the current call to
** this function resulted in the heap subsystem actually being shutdown.
*/
sqlite3_data_directory = 0;
sqlite3_temp_directory = 0;
#endif
}
if( sqlite3GlobalConfig.isMutexInit ){
sqlite3MutexEnd();
sqlite3GlobalConfig.isMutexInit = 0;
}
return SQLITE_OK;
|
| ︙ | ︙ | |||
113496 113497 113498 113499 113500 113501 113502 113503 113504 |
pDestructor->nRef--;
if( pDestructor->nRef==0 ){
pDestructor->xDestroy(pDestructor->pUserData);
sqlite3DbFree(db, pDestructor);
}
}
}
/*
| | > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > | | | > | > | | | | > > > > > | | > > > > > > > > > > > | | > > > > > > > > | > > | > > > > > | | | | > > > > > > > > > > > | > > > > < < | 111922 111923 111924 111925 111926 111927 111928 111929 111930 111931 111932 111933 111934 111935 111936 111937 111938 111939 111940 111941 111942 111943 111944 111945 111946 111947 111948 111949 111950 111951 111952 111953 111954 111955 111956 111957 111958 111959 111960 111961 111962 111963 111964 111965 111966 111967 111968 111969 111970 111971 111972 111973 111974 111975 111976 111977 111978 111979 111980 111981 111982 111983 111984 111985 111986 111987 111988 111989 111990 111991 111992 111993 111994 111995 111996 111997 111998 111999 112000 112001 112002 112003 112004 112005 112006 112007 112008 112009 112010 112011 112012 112013 112014 112015 112016 112017 112018 112019 112020 112021 112022 112023 112024 112025 112026 112027 112028 112029 112030 112031 112032 112033 112034 112035 112036 112037 112038 112039 112040 112041 112042 112043 112044 112045 112046 112047 112048 112049 112050 112051 112052 112053 112054 112055 112056 112057 112058 112059 112060 112061 112062 112063 112064 112065 112066 112067 112068 112069 112070 112071 112072 112073 112074 112075 112076 112077 112078 112079 112080 112081 112082 112083 112084 112085 112086 |
pDestructor->nRef--;
if( pDestructor->nRef==0 ){
pDestructor->xDestroy(pDestructor->pUserData);
sqlite3DbFree(db, pDestructor);
}
}
}
/*
** Disconnect all sqlite3_vtab objects that belong to database connection
** db. This is called when db is being closed.
*/
static void disconnectAllVtab(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
int i;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
if( db->aDb[i].pSchema ){
HashElem *p;
for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
Table *pTab = (Table *)sqliteHashData(p);
if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
}
}
}
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
#endif
}
/*
** Return TRUE if database connection db has unfinalized prepared
** statements or unfinished sqlite3_backup objects.
*/
static int connectionIsBusy(sqlite3 *db){
int j;
assert( sqlite3_mutex_held(db->mutex) );
if( db->pVdbe ) return 1;
for(j=0; j<db->nDb; j++){
Btree *pBt = db->aDb[j].pBt;
if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1;
}
return 0;
}
/*
** Close an existing SQLite database
*/
static int sqlite3Close(sqlite3 *db, int forceZombie){
if( !db ){
return SQLITE_OK;
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
/* Force xDisconnect calls on all virtual tables */
disconnectAllVtab(db);
/* If a transaction is open, the disconnectAllVtab() call above
** will not have called the xDisconnect() method on any virtual
** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
** call will do so. We need to do this before the check for active
** SQL statements below, as the v-table implementation may be storing
** some prepared statements internally.
*/
sqlite3VtabRollback(db);
/* Legacy behavior (sqlite3_close() behavior) is to return
** SQLITE_BUSY if the connection can not be closed immediately.
*/
if( !forceZombie && connectionIsBusy(db) ){
sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
"statements or unfinished backups");
sqlite3_mutex_leave(db->mutex);
return SQLITE_BUSY;
}
/* Convert the connection into a zombie and then close it.
*/
db->magic = SQLITE_MAGIC_ZOMBIE;
sqlite3LeaveMutexAndCloseZombie(db);
return SQLITE_OK;
}
/*
** Two variations on the public interface for closing a database
** connection. The sqlite3_close() version returns SQLITE_BUSY and
** leaves the connection option if there are unfinalized prepared
** statements or unfinished sqlite3_backups. The sqlite3_close_v2()
** version forces the connection to become a zombie if there are
** unclosed resources, and arranges for deallocation when the last
** prepare statement or sqlite3_backup closes.
*/
SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
** Close the mutex on database connection db.
**
** Furthermore, if database connection db is a zombie (meaning that there
** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
** every sqlite3_stmt has now been finalized and every sqlite3_backup has
** finished, then free all resources.
*/
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
HashElem *i; /* Hash table iterator */
int j;
/* If there are outstanding sqlite3_stmt or sqlite3_backup objects
** or if the connection has not yet been closed by sqlite3_close_v2(),
** then just leave the mutex and return.
*/
if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){
sqlite3_mutex_leave(db->mutex);
return;
}
/* If we reach this point, it means that the database connection has
** closed all sqlite3_stmt and sqlite3_backup objects and has been
** pased to sqlite3_close (meaning that it is a zombie). Therefore,
** go ahead and free all resources.
*/
/* Free any outstanding Savepoint structures. */
sqlite3CloseSavepoints(db);
/* Close all database connections */
for(j=0; j<db->nDb; j++){
struct Db *pDb = &db->aDb[j];
if( pDb->pBt ){
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
if( j!=1 ){
pDb->pSchema = 0;
}
}
}
/* Clear the TEMP schema separately and last */
if( db->aDb[1].pSchema ){
sqlite3SchemaClear(db->aDb[1].pSchema);
}
sqlite3VtabUnlockList(db);
/* Free up the array of auxiliary databases */
sqlite3CollapseDatabaseArray(db);
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
/* Tell the code in notify.c that the connection no longer holds any
** locks and does not require any further unlock-notify callbacks.
*/
sqlite3ConnectionClosed(db);
for(j=0; j<ArraySize(db->aFunc.a); j++){
FuncDef *pNext, *pHash, *p;
for(p=db->aFunc.a[j]; p; p=pHash){
pHash = p->pHash;
while( p ){
functionDestroy(db, p);
pNext = p->pNext;
|
| ︙ | ︙ | |||
113622 113623 113624 113625 113626 113627 113628 |
db->magic = SQLITE_MAGIC_CLOSED;
sqlite3_mutex_free(db->mutex);
assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
sqlite3_free(db);
| < | 112130 112131 112132 112133 112134 112135 112136 112137 112138 112139 112140 112141 112142 112143 |
db->magic = SQLITE_MAGIC_CLOSED;
sqlite3_mutex_free(db->mutex);
assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
sqlite3_free(db);
}
/*
** Rollback all database files. If tripCode is not SQLITE_OK, then
** any open cursors are invalidated ("tripped" - as in "tripping a circuit
** breaker") and made to return tripCode if there are any further
** attempts to use that cursor.
|
| ︙ | ︙ | |||
113651 113652 113653 113654 113655 113656 113657 |
}
}
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
if( db->flags&SQLITE_InternChanges ){
sqlite3ExpirePreparedStatements(db);
| | | 112158 112159 112160 112161 112162 112163 112164 112165 112166 112167 112168 112169 112170 112171 112172 |
}
}
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
if( db->flags&SQLITE_InternChanges ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
}
/* Any deferred constraint violations have now been resolved. */
db->nDeferredCons = 0;
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
|
| ︙ | ︙ | |||
114789 114790 114791 114792 114793 114794 114795 114796 114797 114798 |
zModeType = "cache";
}
if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){
static struct OpenMode aOpenMode[] = {
{ "ro", SQLITE_OPEN_READONLY },
{ "rw", SQLITE_OPEN_READWRITE },
{ "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
{ 0, 0 }
};
| > | > | > | 113296 113297 113298 113299 113300 113301 113302 113303 113304 113305 113306 113307 113308 113309 113310 113311 113312 113313 113314 113315 113316 113317 113318 113319 113320 113321 113322 113323 113324 113325 113326 113327 113328 113329 113330 113331 113332 113333 113334 113335 113336 113337 113338 113339 113340 113341 113342 113343 113344 113345 113346 113347 113348 113349 113350 113351 113352 113353 113354 113355 |
zModeType = "cache";
}
if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){
static struct OpenMode aOpenMode[] = {
{ "ro", SQLITE_OPEN_READONLY },
{ "rw", SQLITE_OPEN_READWRITE },
{ "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
{ "memory", SQLITE_OPEN_MEMORY },
{ 0, 0 }
};
mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY;
aMode = aOpenMode;
limit = mask & flags;
zModeType = "access";
}
if( aMode ){
int i;
int mode = 0;
for(i=0; aMode[i].z; i++){
const char *z = aMode[i].z;
if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){
mode = aMode[i].mode;
break;
}
}
if( mode==0 ){
*pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal);
rc = SQLITE_ERROR;
goto parse_uri_out;
}
if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){
*pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s",
zModeType, zVal);
rc = SQLITE_PERM;
goto parse_uri_out;
}
flags = (flags & ~mask) | mode;
}
}
zOpt = &zVal[nVal+1];
}
}else{
zFile = sqlite3_malloc(nUri+2);
if( !zFile ) return SQLITE_NOMEM;
memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0';
zFile[nUri+1] = '\0';
flags &= ~SQLITE_OPEN_URI;
}
*ppVfs = sqlite3_vfs_find(zVfs);
if( *ppVfs==0 ){
*pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
rc = SQLITE_ERROR;
}
|
| ︙ | ︙ | |||
117271 117272 117273 117274 117275 117276 117277 |
SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
| | > > > > > > > | 115781 115782 115783 115784 115785 115786 115787 115788 115789 115790 115791 115792 115793 115794 115795 115796 115797 115798 115799 115800 115801 115802 115803 115804 115805 115806 |
SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **);
SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int);
SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
#endif
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
#endif /* _FTSINT_H */
/************** End of fts3Int.h *********************************************/
/************** Continuing where we left off in fts3.c ***********************/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
|
| ︙ | ︙ | |||
120545 120546 120547 120548 120549 120550 120551 120552 120553 120554 120555 120556 120557 120558 120559 120560 120561 120562 120563 120564 120565 120566 120567 120568 120569 120570 120571 120572 120573 120574 120575 120576 120577 120578 |
**
** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
** to by the argument to point to the "simple" tokenizer implementation.
** And so on.
*/
SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#ifdef SQLITE_ENABLE_ICU
SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#endif
/*
** Initialise the fts3 extension. If this extension is built as part
** of the sqlite library, then this function is called directly by
** SQLite. If fts3 is built as a dynamically loadable extension, this
** function is called by the sqlite3_extension_init() entry point.
*/
SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
int rc = SQLITE_OK;
Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0;
#ifdef SQLITE_ENABLE_ICU
const sqlite3_tokenizer_module *pIcu = 0;
sqlite3Fts3IcuTokenizerModule(&pIcu);
#endif
#ifdef SQLITE_TEST
rc = sqlite3Fts3InitTerm(db);
if( rc!=SQLITE_OK ) return rc;
#endif
rc = sqlite3Fts3InitAux(db);
| > > > > > > > > > > | 119062 119063 119064 119065 119066 119067 119068 119069 119070 119071 119072 119073 119074 119075 119076 119077 119078 119079 119080 119081 119082 119083 119084 119085 119086 119087 119088 119089 119090 119091 119092 119093 119094 119095 119096 119097 119098 119099 119100 119101 119102 119103 119104 119105 |
**
** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
** to by the argument to point to the "simple" tokenizer implementation.
** And so on.
*/
SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule);
#endif
#ifdef SQLITE_ENABLE_ICU
SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#endif
/*
** Initialise the fts3 extension. If this extension is built as part
** of the sqlite library, then this function is called directly by
** SQLite. If fts3 is built as a dynamically loadable extension, this
** function is called by the sqlite3_extension_init() entry point.
*/
SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
int rc = SQLITE_OK;
Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0;
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
const sqlite3_tokenizer_module *pUnicode = 0;
#endif
#ifdef SQLITE_ENABLE_ICU
const sqlite3_tokenizer_module *pIcu = 0;
sqlite3Fts3IcuTokenizerModule(&pIcu);
#endif
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
sqlite3Fts3UnicodeTokenizer(&pUnicode);
#endif
#ifdef SQLITE_TEST
rc = sqlite3Fts3InitTerm(db);
if( rc!=SQLITE_OK ) return rc;
#endif
rc = sqlite3Fts3InitAux(db);
|
| ︙ | ︙ | |||
120589 120590 120591 120592 120593 120594 120595 120596 120597 120598 120599 120600 120601 120602 |
sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
}
/* Load the built-in tokenizers into the hash table */
if( rc==SQLITE_OK ){
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
#ifdef SQLITE_ENABLE_ICU
|| (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
#endif
){
rc = SQLITE_NOMEM;
}
}
| > > > > | 119116 119117 119118 119119 119120 119121 119122 119123 119124 119125 119126 119127 119128 119129 119130 119131 119132 119133 |
sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
}
/* Load the built-in tokenizers into the hash table */
if( rc==SQLITE_OK ){
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|| sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
#endif
#ifdef SQLITE_ENABLE_ICU
|| (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
#endif
){
rc = SQLITE_NOMEM;
}
}
|
| ︙ | ︙ | |||
120936 120937 120938 120939 120940 120941 120942 | */ SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( int bDescIdx, /* True if the doclist is desc */ char *aDoclist, /* Pointer to entire doclist */ int nDoclist, /* Length of aDoclist in bytes */ char **ppIter, /* IN/OUT: Iterator pointer */ sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ | | | 119467 119468 119469 119470 119471 119472 119473 119474 119475 119476 119477 119478 119479 119480 119481 |
*/
SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(
int bDescIdx, /* True if the doclist is desc */
char *aDoclist, /* Pointer to entire doclist */
int nDoclist, /* Length of aDoclist in bytes */
char **ppIter, /* IN/OUT: Iterator pointer */
sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */
int *pnList, /* OUT: List length pointer */
u8 *pbEof /* OUT: End-of-file flag */
){
char *p = *ppIter;
assert( nDoclist>0 );
assert( *pbEof==0 );
assert( p || *piDocid==0 );
|
| ︙ | ︙ | |||
120982 120983 120984 120985 120986 120987 120988 120989 120990 120991 120992 120993 120994 120995 |
char *pSave = p;
fts3ReversePoslist(aDoclist, &p);
*pnList = (int)(pSave - p);
}
*ppIter = p;
}
}
/*
** Attempt to move the phrase iterator to point to the next matching docid.
** If an error occurs, return an SQLite error code. Otherwise, return
** SQLITE_OK.
**
** If there is no "next" entry and no error occurs, then *pbEof is set to
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 119513 119514 119515 119516 119517 119518 119519 119520 119521 119522 119523 119524 119525 119526 119527 119528 119529 119530 119531 119532 119533 119534 119535 119536 119537 119538 119539 119540 119541 119542 119543 119544 119545 119546 119547 119548 119549 119550 119551 119552 119553 119554 119555 119556 119557 119558 119559 119560 119561 |
char *pSave = p;
fts3ReversePoslist(aDoclist, &p);
*pnList = (int)(pSave - p);
}
*ppIter = p;
}
}
/*
** Iterate forwards through a doclist.
*/
SQLITE_PRIVATE void sqlite3Fts3DoclistNext(
int bDescIdx, /* True if the doclist is desc */
char *aDoclist, /* Pointer to entire doclist */
int nDoclist, /* Length of aDoclist in bytes */
char **ppIter, /* IN/OUT: Iterator pointer */
sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */
u8 *pbEof /* OUT: End-of-file flag */
){
char *p = *ppIter;
assert( nDoclist>0 );
assert( *pbEof==0 );
assert( p || *piDocid==0 );
assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) );
if( p==0 ){
p = aDoclist;
p += sqlite3Fts3GetVarint(p, piDocid);
}else{
fts3PoslistCopy(0, &p);
if( p>=&aDoclist[nDoclist] ){
*pbEof = 1;
}else{
sqlite3_int64 iVar;
p += sqlite3Fts3GetVarint(p, &iVar);
*piDocid += ((bDescIdx ? -1 : 1) * iVar);
}
}
*ppIter = p;
}
/*
** Attempt to move the phrase iterator to point to the next matching docid.
** If an error occurs, return an SQLite error code. Otherwise, return
** SQLITE_OK.
**
** If there is no "next" entry and no error occurs, then *pbEof is set to
|
| ︙ | ︙ | |||
122138 122139 122140 122141 122142 122143 122144 | ** for 'X' is requested, the buffer returned may contain: ** ** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00 ** ** This function works regardless of whether or not the phrase is deferred, ** incremental, or neither. */ | | | > | > > > > > > > | | > | > > > > | > > > > > > > | > > > > > > > > > > > > > | | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | > | 120704 120705 120706 120707 120708 120709 120710 120711 120712 120713 120714 120715 120716 120717 120718 120719 120720 120721 120722 120723 120724 120725 120726 120727 120728 120729 120730 120731 120732 120733 120734 120735 120736 120737 120738 120739 120740 120741 120742 120743 120744 120745 120746 120747 120748 120749 120750 120751 120752 120753 120754 120755 120756 120757 120758 120759 120760 120761 120762 120763 120764 120765 120766 120767 120768 120769 120770 120771 120772 120773 120774 120775 120776 120777 120778 120779 120780 120781 120782 120783 120784 120785 120786 120787 120788 120789 120790 120791 120792 120793 120794 120795 120796 120797 120798 120799 120800 120801 120802 120803 120804 120805 120806 120807 120808 120809 120810 120811 120812 120813 |
** for 'X' is requested, the buffer returned may contain:
**
** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00
**
** This function works regardless of whether or not the phrase is deferred,
** incremental, or neither.
*/
SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
Fts3Cursor *pCsr, /* FTS3 cursor object */
Fts3Expr *pExpr, /* Phrase to return doclist for */
int iCol, /* Column to return position list for */
char **ppOut /* OUT: Pointer to position list */
){
Fts3Phrase *pPhrase = pExpr->pPhrase;
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
char *pIter;
int iThis;
sqlite3_int64 iDocid;
/* If this phrase is applies specifically to some column other than
** column iCol, return a NULL pointer. */
*ppOut = 0;
assert( iCol>=0 && iCol<pTab->nColumn );
if( (pPhrase->iColumn<pTab->nColumn && pPhrase->iColumn!=iCol) ){
return SQLITE_OK;
}
iDocid = pExpr->iDocid;
pIter = pPhrase->doclist.pList;
if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
int bOr = 0;
u8 bEof = 0;
Fts3Expr *p;
/* Check if this phrase descends from an OR expression node. If not,
** return NULL. Otherwise, the entry that corresponds to docid
** pCsr->iPrevId may lie earlier in the doclist buffer. */
for(p=pExpr->pParent; p; p=p->pParent){
if( p->eType==FTSQUERY_OR ) bOr = 1;
}
if( bOr==0 ) return SQLITE_OK;
/* This is the descendent of an OR node. In this case we cannot use
** an incremental phrase. Load the entire doclist for the phrase
** into memory in this case. */
if( pPhrase->bIncr ){
int rc = SQLITE_OK;
int bEofSave = pExpr->bEof;
fts3EvalRestart(pCsr, pExpr, &rc);
while( rc==SQLITE_OK && !pExpr->bEof ){
fts3EvalNextRow(pCsr, pExpr, &rc);
if( bEofSave==0 && pExpr->iDocid==iDocid ) break;
}
pIter = pPhrase->doclist.pList;
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
if( rc!=SQLITE_OK ) return rc;
}
if( pExpr->bEof ){
pIter = 0;
iDocid = 0;
}
bEof = (pPhrase->doclist.nAll==0);
assert( bDescDoclist==0 || bDescDoclist==1 );
assert( pCsr->bDesc==0 || pCsr->bDesc==1 );
if( pCsr->bDesc==bDescDoclist ){
int dummy;
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
sqlite3Fts3DoclistPrev(
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
&pIter, &iDocid, &dummy, &bEof
);
}
}else{
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
sqlite3Fts3DoclistNext(
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
&pIter, &iDocid, &bEof
);
}
}
if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
}
if( pIter==0 ) return SQLITE_OK;
if( *pIter==0x01 ){
pIter++;
pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
}else{
iThis = 0;
}
while( iThis<iCol ){
fts3ColumnlistCopy(0, &pIter);
if( *pIter==0x00 ) return 0;
pIter++;
pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
}
*ppOut = ((iCol==iThis)?pIter:0);
return SQLITE_OK;
}
/*
** Free all components of the Fts3Phrase structure that were allocated by
** the eval module. Specifically, this means to free:
**
** * the contents of pPhrase->doclist, and
|
| ︙ | ︙ | |||
124954 124955 124956 124957 124958 124959 124960 | /* #include <tcl.h> */ /* #include <string.h> */ /* ** Implementation of a special SQL scalar function for testing tokenizers ** designed to be used in concert with the Tcl testing framework. This | | | < | 123582 123583 123584 123585 123586 123587 123588 123589 123590 123591 123592 123593 123594 123595 123596 123597 123598 | /* #include <tcl.h> */ /* #include <string.h> */ /* ** Implementation of a special SQL scalar function for testing tokenizers ** designed to be used in concert with the Tcl testing framework. This ** function must be called with two or more arguments: ** ** SELECT <function-name>(<key-name>, ..., <input-string>); ** ** where <function-name> is the name passed as the second argument ** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') ** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test'). ** ** The return value is a string that may be interpreted as a Tcl ** list. For each token in the <input-string>, three elements are |
| ︙ | ︙ | |||
124994 124995 124996 124997 124998 124999 125000 | const char *zErr = 0; const char *zName; int nName; const char *zInput; int nInput; | | > | > > > < < < < > > > > | | 123621 123622 123623 123624 123625 123626 123627 123628 123629 123630 123631 123632 123633 123634 123635 123636 123637 123638 123639 123640 123641 123642 123643 123644 123645 123646 123647 123648 123649 123650 123651 123652 123653 123654 123655 123656 123657 123658 123659 123660 123661 123662 123663 123664 123665 123666 123667 123668 123669 123670 123671 123672 123673 |
const char *zErr = 0;
const char *zName;
int nName;
const char *zInput;
int nInput;
const char *azArg[64];
const char *zToken;
int nToken;
int iStart;
int iEnd;
int iPos;
int i;
Tcl_Obj *pRet;
if( argc<2 ){
sqlite3_result_error(context, "insufficient arguments", -1);
return;
}
nName = sqlite3_value_bytes(argv[0]);
zName = (const char *)sqlite3_value_text(argv[0]);
nInput = sqlite3_value_bytes(argv[argc-1]);
zInput = (const char *)sqlite3_value_text(argv[argc-1]);
pHash = (Fts3Hash *)sqlite3_user_data(context);
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
return;
}
pRet = Tcl_NewObj();
Tcl_IncrRefCount(pRet);
for(i=1; i<argc-1; i++){
azArg[i-1] = (const char *)sqlite3_value_text(argv[i]);
}
if( SQLITE_OK!=p->xCreate(argc-2, azArg, &pTokenizer) ){
zErr = "error in xCreate()";
goto finish;
}
pTokenizer->pModule = p;
if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){
zErr = "error in xOpen()";
goto finish;
|
| ︙ | ︙ | |||
125212 125213 125214 125215 125216 125217 125218 |
rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0);
}
if( SQLITE_OK==rc ){
rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0);
}
#ifdef SQLITE_TEST
if( SQLITE_OK==rc ){
| | < < < | 123843 123844 123845 123846 123847 123848 123849 123850 123851 123852 123853 123854 123855 123856 123857 |
rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0);
}
if( SQLITE_OK==rc ){
rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0);
}
#ifdef SQLITE_TEST
if( SQLITE_OK==rc ){
rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0);
}
if( SQLITE_OK==rc ){
rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0);
}
#endif
#ifdef SQLITE_TEST
|
| ︙ | ︙ | |||
125606 125607 125608 125609 125610 125611 125612 |
**
** fts3SegReaderNext()
** fts3SegReaderFirstDocid()
** fts3SegReaderNextDocid()
*/
struct Fts3SegReader {
int iIdx; /* Index within level, or 0x7FFFFFFF for PT */
| > | | 124234 124235 124236 124237 124238 124239 124240 124241 124242 124243 124244 124245 124246 124247 124248 124249 |
**
** fts3SegReaderNext()
** fts3SegReaderFirstDocid()
** fts3SegReaderNextDocid()
*/
struct Fts3SegReader {
int iIdx; /* Index within level, or 0x7FFFFFFF for PT */
u8 bLookup; /* True for a lookup only */
u8 rootOnly; /* True for a root-only reader */
sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */
sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */
sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */
sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */
char *aNode; /* Pointer to node data (or NULL) */
|
| ︙ | ︙ | |||
125640 125641 125642 125643 125644 125645 125646 | */ char *pOffsetList; int nOffsetList; /* For descending pending seg-readers only */ sqlite3_int64 iDocid; }; #define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) | | | 124269 124270 124271 124272 124273 124274 124275 124276 124277 124278 124279 124280 124281 124282 124283 | */ char *pOffsetList; int nOffsetList; /* For descending pending seg-readers only */ sqlite3_int64 iDocid; }; #define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) #define fts3SegReaderIsRootOnly(p) ((p)->rootOnly!=0) /* ** An instance of this structure is used to create a segment b-tree in the ** database. The internal details of this type are only accessed by the ** following functions: ** ** fts3SegWriterAdd() |
| ︙ | ︙ | |||
127051 127052 127053 127054 127055 127056 127057 |
pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
if( !pReader ){
return SQLITE_NOMEM;
}
memset(pReader, 0, sizeof(Fts3SegReader));
pReader->iIdx = iAge;
| | > | 125680 125681 125682 125683 125684 125685 125686 125687 125688 125689 125690 125691 125692 125693 125694 125695 125696 125697 125698 125699 125700 125701 125702 |
pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
if( !pReader ){
return SQLITE_NOMEM;
}
memset(pReader, 0, sizeof(Fts3SegReader));
pReader->iIdx = iAge;
pReader->bLookup = bLookup!=0;
pReader->iStartBlock = iStartLeaf;
pReader->iLeafEndBlock = iEndLeaf;
pReader->iEndBlock = iEndBlock;
if( nExtra ){
/* The entire segment is stored in the root node. */
pReader->aNode = (char *)&pReader[1];
pReader->rootOnly = 1;
pReader->nNode = nRoot;
memcpy(pReader->aNode, zRoot, nRoot);
memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
}else{
pReader->iCurrentBlock = iStartLeaf-1;
}
*ppReader = pReader;
|
| ︙ | ︙ | |||
128644 128645 128646 128647 128648 128649 128650 |
if( sqlite3_step(pStmt)==SQLITE_ROW ){
fts3DecodeIntArray(nStat, a,
sqlite3_column_blob(pStmt, 0),
sqlite3_column_bytes(pStmt, 0));
}else{
memset(a, 0, sizeof(u32)*(nStat) );
}
| | > > > > > | 127274 127275 127276 127277 127278 127279 127280 127281 127282 127283 127284 127285 127286 127287 127288 127289 127290 127291 127292 127293 |
if( sqlite3_step(pStmt)==SQLITE_ROW ){
fts3DecodeIntArray(nStat, a,
sqlite3_column_blob(pStmt, 0),
sqlite3_column_bytes(pStmt, 0));
}else{
memset(a, 0, sizeof(u32)*(nStat) );
}
rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
sqlite3_free(a);
*pRC = rc;
return;
}
if( nChng<0 && a[0]<(u32)(-nChng) ){
a[0] = 0;
}else{
a[0] += nChng;
}
for(i=0; i<p->nColumn+1; i++){
u32 x = a[i+1];
|
| ︙ | ︙ | |||
131218 131219 131220 131221 131222 131223 131224 131225 131226 |
** This function is an fts3ExprIterate() callback used by fts3BestSnippet().
** Each invocation populates an element of the SnippetIter.aPhrase[] array.
*/
static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
SnippetIter *p = (SnippetIter *)ctx;
SnippetPhrase *pPhrase = &p->aPhrase[iPhrase];
char *pCsr;
pPhrase->nToken = pExpr->pPhrase->nToken;
| > < | > > | > | | 129853 129854 129855 129856 129857 129858 129859 129860 129861 129862 129863 129864 129865 129866 129867 129868 129869 129870 129871 129872 129873 129874 129875 129876 129877 129878 129879 129880 129881 129882 129883 129884 129885 129886 129887 |
** This function is an fts3ExprIterate() callback used by fts3BestSnippet().
** Each invocation populates an element of the SnippetIter.aPhrase[] array.
*/
static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
SnippetIter *p = (SnippetIter *)ctx;
SnippetPhrase *pPhrase = &p->aPhrase[iPhrase];
char *pCsr;
int rc;
pPhrase->nToken = pExpr->pPhrase->nToken;
rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr);
assert( rc==SQLITE_OK || pCsr==0 );
if( pCsr ){
int iFirst = 0;
pPhrase->pList = pCsr;
fts3GetDeltaPosition(&pCsr, &iFirst);
assert( iFirst>=0 );
pPhrase->pHead = pCsr;
pPhrase->pTail = pCsr;
pPhrase->iHead = iFirst;
pPhrase->iTail = iFirst;
}else{
assert( rc!=SQLITE_OK || (
pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0
));
}
return rc;
}
/*
** Select the fragment of text consisting of nFragment contiguous tokens
** from column iCol that represent the "best" snippet. The best snippet
** is the snippet with the highest score, where scores are calculated
** by adding:
|
| ︙ | ︙ | |||
131628 131629 131630 131631 131632 131633 131634 131635 131636 131637 131638 |
** array that are different for each row returned by the query.
*/
static int fts3ExprLocalHitsCb(
Fts3Expr *pExpr, /* Phrase expression node */
int iPhrase, /* Phrase number */
void *pCtx /* Pointer to MatchInfo structure */
){
MatchInfo *p = (MatchInfo *)pCtx;
int iStart = iPhrase * p->nCol * 3;
int i;
| > | | | | 130266 130267 130268 130269 130270 130271 130272 130273 130274 130275 130276 130277 130278 130279 130280 130281 130282 130283 130284 130285 130286 130287 130288 130289 130290 130291 130292 130293 130294 130295 |
** array that are different for each row returned by the query.
*/
static int fts3ExprLocalHitsCb(
Fts3Expr *pExpr, /* Phrase expression node */
int iPhrase, /* Phrase number */
void *pCtx /* Pointer to MatchInfo structure */
){
int rc = SQLITE_OK;
MatchInfo *p = (MatchInfo *)pCtx;
int iStart = iPhrase * p->nCol * 3;
int i;
for(i=0; i<p->nCol && rc==SQLITE_OK; i++){
char *pCsr;
rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr);
if( pCsr ){
p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr);
}else{
p->aMatchinfo[iStart+i*3] = 0;
}
}
return rc;
}
static int fts3MatchinfoCheck(
Fts3Table *pTab,
char cArg,
char **pzErr
){
|
| ︙ | ︙ | |||
131803 131804 131805 131806 131807 131808 131809 131810 |
}
for(iCol=0; iCol<pInfo->nCol; iCol++){
int nLcs = 0; /* LCS value for this column */
int nLive = 0; /* Number of iterators in aIter not at EOF */
for(i=0; i<pInfo->nPhrase; i++){
LcsIterator *pIt = &aIter[i];
| > | > | 130442 130443 130444 130445 130446 130447 130448 130449 130450 130451 130452 130453 130454 130455 130456 130457 130458 130459 |
}
for(iCol=0; iCol<pInfo->nCol; iCol++){
int nLcs = 0; /* LCS value for this column */
int nLive = 0; /* Number of iterators in aIter not at EOF */
for(i=0; i<pInfo->nPhrase; i++){
int rc;
LcsIterator *pIt = &aIter[i];
rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
if( rc!=SQLITE_OK ) return rc;
if( pIt->pRead ){
pIt->iPos = pIt->iPosOffset;
fts3LcsIteratorAdvance(&aIter[i]);
nLive++;
}
}
|
| ︙ | ︙ | |||
132156 132157 132158 132159 132160 132161 132162 132163 132164 |
*/
static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
TermOffsetCtx *p = (TermOffsetCtx *)ctx;
int nTerm; /* Number of tokens in phrase */
int iTerm; /* For looping through nTerm phrase terms */
char *pList; /* Pointer to position list for phrase */
int iPos = 0; /* First position in position-list */
UNUSED_PARAMETER(iPhrase);
| > | | | 130797 130798 130799 130800 130801 130802 130803 130804 130805 130806 130807 130808 130809 130810 130811 130812 130813 130814 130815 130816 130817 130818 130819 130820 130821 130822 130823 130824 130825 130826 130827 130828 |
*/
static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
TermOffsetCtx *p = (TermOffsetCtx *)ctx;
int nTerm; /* Number of tokens in phrase */
int iTerm; /* For looping through nTerm phrase terms */
char *pList; /* Pointer to position list for phrase */
int iPos = 0; /* First position in position-list */
int rc;
UNUSED_PARAMETER(iPhrase);
rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pList);
nTerm = pExpr->pPhrase->nToken;
if( pList ){
fts3GetDeltaPosition(&pList, &iPos);
assert( iPos>=0 );
}
for(iTerm=0; iTerm<nTerm; iTerm++){
TermOffset *pT = &p->aTerm[p->iTerm++];
pT->iOff = nTerm-iTerm-1;
pT->pList = pList;
pT->iPos = iPos;
}
return rc;
}
/*
** Implementation of offsets() function.
*/
SQLITE_PRIVATE void sqlite3Fts3Offsets(
sqlite3_context *pCtx, /* SQLite function call context */
|
| ︙ | ︙ | |||
132360 132361 132362 132363 132364 132365 132366 132367 132368 132369 132370 132371 132372 132373 |
sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
}
}
#endif
/************** End of fts3_snippet.c ****************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 131002 131003 131004 131005 131006 131007 131008 131009 131010 131011 131012 131013 131014 131015 131016 131017 131018 131019 131020 131021 131022 131023 131024 131025 131026 131027 131028 131029 131030 131031 131032 131033 131034 131035 131036 131037 131038 131039 131040 131041 131042 131043 131044 131045 131046 131047 131048 131049 131050 131051 131052 131053 131054 131055 131056 131057 131058 131059 131060 131061 131062 131063 131064 131065 131066 131067 131068 131069 131070 131071 131072 131073 131074 131075 131076 131077 131078 131079 131080 131081 131082 131083 131084 131085 131086 131087 131088 131089 131090 131091 131092 131093 131094 131095 131096 131097 131098 131099 131100 131101 131102 131103 131104 131105 131106 131107 131108 131109 131110 131111 131112 131113 131114 131115 131116 131117 131118 131119 131120 131121 131122 131123 131124 131125 131126 131127 131128 131129 131130 131131 131132 131133 131134 131135 131136 131137 131138 131139 131140 131141 131142 131143 131144 131145 131146 131147 131148 131149 131150 131151 131152 131153 131154 131155 131156 131157 131158 131159 131160 131161 131162 131163 131164 131165 131166 131167 131168 131169 131170 131171 131172 131173 131174 131175 131176 131177 131178 131179 131180 131181 131182 131183 131184 131185 131186 131187 131188 131189 131190 131191 131192 131193 131194 131195 131196 131197 131198 131199 131200 131201 131202 131203 131204 131205 131206 131207 131208 131209 131210 131211 131212 131213 131214 131215 131216 131217 131218 131219 131220 131221 131222 131223 131224 131225 131226 131227 131228 131229 131230 131231 131232 131233 131234 131235 131236 131237 131238 131239 131240 131241 131242 131243 131244 131245 131246 131247 131248 131249 131250 131251 131252 131253 131254 131255 131256 131257 131258 131259 131260 131261 131262 131263 131264 131265 131266 131267 131268 131269 131270 131271 131272 131273 131274 131275 131276 131277 131278 131279 131280 131281 131282 131283 131284 131285 131286 131287 131288 131289 131290 131291 131292 131293 131294 131295 131296 131297 131298 131299 131300 131301 131302 131303 131304 131305 131306 131307 131308 131309 131310 131311 131312 131313 131314 131315 131316 131317 131318 131319 131320 131321 131322 131323 131324 131325 131326 131327 131328 131329 131330 131331 131332 131333 131334 131335 131336 131337 131338 131339 131340 131341 131342 131343 131344 131345 131346 131347 131348 131349 131350 131351 131352 131353 131354 131355 131356 131357 131358 131359 131360 131361 131362 131363 131364 131365 131366 131367 131368 131369 131370 131371 131372 131373 131374 131375 131376 131377 131378 131379 131380 131381 131382 131383 131384 131385 131386 131387 131388 131389 131390 131391 131392 131393 131394 131395 131396 131397 131398 131399 131400 131401 131402 131403 131404 131405 131406 131407 131408 131409 131410 131411 131412 131413 131414 131415 131416 131417 131418 131419 131420 131421 131422 131423 131424 131425 131426 131427 131428 131429 131430 131431 131432 131433 131434 131435 131436 131437 131438 131439 131440 131441 131442 131443 131444 131445 131446 131447 131448 131449 131450 131451 131452 131453 131454 131455 131456 131457 131458 131459 131460 131461 131462 131463 131464 131465 131466 131467 131468 131469 131470 131471 131472 131473 131474 131475 131476 131477 131478 131479 131480 131481 131482 131483 131484 131485 131486 131487 131488 131489 131490 131491 131492 131493 131494 131495 131496 131497 131498 131499 131500 131501 131502 131503 131504 131505 131506 131507 131508 131509 131510 131511 131512 131513 131514 131515 131516 131517 131518 131519 131520 131521 131522 131523 131524 131525 131526 131527 131528 131529 131530 131531 131532 131533 131534 131535 131536 131537 131538 131539 131540 131541 131542 131543 131544 131545 131546 131547 131548 131549 131550 131551 131552 131553 131554 131555 131556 131557 131558 131559 131560 131561 131562 131563 131564 131565 131566 131567 131568 131569 131570 131571 131572 131573 131574 131575 131576 131577 131578 131579 131580 131581 131582 131583 131584 131585 131586 131587 131588 131589 131590 131591 131592 131593 131594 131595 131596 131597 131598 131599 131600 131601 131602 131603 131604 131605 131606 131607 131608 131609 131610 131611 131612 131613 131614 131615 131616 131617 131618 131619 131620 131621 131622 131623 131624 131625 131626 131627 131628 131629 131630 131631 131632 131633 131634 131635 131636 131637 131638 131639 131640 131641 131642 131643 131644 131645 131646 131647 131648 131649 131650 131651 131652 131653 131654 131655 131656 131657 131658 131659 131660 131661 131662 131663 131664 131665 131666 131667 131668 131669 131670 131671 131672 131673 131674 131675 131676 131677 131678 131679 131680 131681 131682 131683 131684 131685 131686 131687 131688 131689 131690 131691 131692 131693 131694 131695 131696 131697 131698 131699 131700 131701 131702 131703 131704 131705 131706 131707 131708 131709 131710 131711 131712 131713 131714 131715 131716 131717 131718 131719 131720 131721 131722 131723 131724 131725 131726 131727 131728 131729 131730 131731 131732 131733 131734 131735 131736 131737 131738 131739 131740 131741 131742 131743 131744 131745 131746 131747 131748 131749 131750 131751 131752 131753 131754 131755 131756 131757 131758 131759 131760 131761 131762 131763 131764 131765 131766 131767 131768 131769 131770 131771 131772 131773 131774 131775 131776 131777 131778 |
sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
}
}
#endif
/************** End of fts3_snippet.c ****************************************/
/************** Begin file fts3_unicode.c ************************************/
/*
** 2012 May 24
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** Implementation of the "unicode" full-text-search tokenizer.
*/
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <assert.h> */
/* #include <stdlib.h> */
/* #include <stdio.h> */
/* #include <string.h> */
/*
** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
** from the sqlite3 source file utf.c. If this file is compiled as part
** of the amalgamation, they are not required.
*/
#ifndef SQLITE_AMALGAMATION
static const unsigned char sqlite3Utf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
#define READ_UTF8(zIn, zTerm, c) \
c = *(zIn++); \
if( c>=0xc0 ){ \
c = sqlite3Utf8Trans1[c-0xc0]; \
while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
c = (c<<6) + (0x3f & *(zIn++)); \
} \
if( c<0x80 \
|| (c&0xFFFFF800)==0xD800 \
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
}
#define WRITE_UTF8(zOut, c) { \
if( c<0x00080 ){ \
*zOut++ = (u8)(c&0xFF); \
} \
else if( c<0x00800 ){ \
*zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
else if( c<0x10000 ){ \
*zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
}else{ \
*zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \
*zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
}
#endif /* ifndef SQLITE_AMALGAMATION */
typedef struct unicode_tokenizer unicode_tokenizer;
typedef struct unicode_cursor unicode_cursor;
struct unicode_tokenizer {
sqlite3_tokenizer base;
int bRemoveDiacritic;
int nException;
int *aiException;
};
struct unicode_cursor {
sqlite3_tokenizer_cursor base;
const unsigned char *aInput; /* Input text being tokenized */
int nInput; /* Size of aInput[] in bytes */
int iOff; /* Current offset within aInput[] */
int iToken; /* Index of next token to be returned */
char *zToken; /* storage for current token */
int nAlloc; /* space allocated at zToken */
};
/*
** Destroy a tokenizer allocated by unicodeCreate().
*/
static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
if( pTokenizer ){
unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer;
sqlite3_free(p->aiException);
sqlite3_free(p);
}
return SQLITE_OK;
}
/*
** As part of a tokenchars= or separators= option, the CREATE VIRTUAL TABLE
** statement has specified that the tokenizer for this table shall consider
** all characters in string zIn/nIn to be separators (if bAlnum==0) or
** token characters (if bAlnum==1).
**
** For each codepoint in the zIn/nIn string, this function checks if the
** sqlite3FtsUnicodeIsalnum() function already returns the desired result.
** If so, no action is taken. Otherwise, the codepoint is added to the
** unicode_tokenizer.aiException[] array. For the purposes of tokenization,
** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all
** codepoints in the aiException[] array.
**
** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic()
** identifies as a diacritic) occurs in the zIn/nIn string it is ignored.
** It is not possible to change the behaviour of the tokenizer with respect
** to these codepoints.
*/
static int unicodeAddExceptions(
unicode_tokenizer *p, /* Tokenizer to add exceptions to */
int bAlnum, /* Replace Isalnum() return value with this */
const char *zIn, /* Array of characters to make exceptions */
int nIn /* Length of z in bytes */
){
const unsigned char *z = (const unsigned char *)zIn;
const unsigned char *zTerm = &z[nIn];
int iCode;
int nEntry = 0;
assert( bAlnum==0 || bAlnum==1 );
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
){
nEntry++;
}
}
if( nEntry ){
int *aNew; /* New aiException[] array */
int nNew; /* Number of valid entries in array aNew[] */
aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
if( aNew==0 ) return SQLITE_NOMEM;
nNew = p->nException;
z = (const unsigned char *)zIn;
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
){
int i, j;
for(i=0; i<nNew && aNew[i]<iCode; i++);
for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
aNew[i] = iCode;
nNew++;
}
}
p->aiException = aNew;
p->nException = nNew;
}
return SQLITE_OK;
}
/*
** Return true if the p->aiException[] array contains the value iCode.
*/
static int unicodeIsException(unicode_tokenizer *p, int iCode){
if( p->nException>0 ){
int *a = p->aiException;
int iLo = 0;
int iHi = p->nException-1;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( iCode==a[iTest] ){
return 1;
}else if( iCode>a[iTest] ){
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
}
return 0;
}
/*
** Return true if, for the purposes of tokenization, codepoint iCode is
** considered a token character (not a separator).
*/
static int unicodeIsAlnum(unicode_tokenizer *p, int iCode){
assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
return sqlite3FtsUnicodeIsalnum(iCode) ^ unicodeIsException(p, iCode);
}
/*
** Create a new tokenizer instance.
*/
static int unicodeCreate(
int nArg, /* Size of array argv[] */
const char * const *azArg, /* Tokenizer creation arguments */
sqlite3_tokenizer **pp /* OUT: New tokenizer handle */
){
unicode_tokenizer *pNew; /* New tokenizer object */
int i;
int rc = SQLITE_OK;
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
if( pNew==NULL ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(unicode_tokenizer));
pNew->bRemoveDiacritic = 1;
for(i=0; rc==SQLITE_OK && i<nArg; i++){
const char *z = azArg[i];
int n = strlen(z);
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
pNew->bRemoveDiacritic = 1;
}
else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
pNew->bRemoveDiacritic = 0;
}
else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
}
else if( n>=11 && memcmp("separators=", z, 11)==0 ){
rc = unicodeAddExceptions(pNew, 0, &z[11], n-11);
}
else{
/* Unrecognized argument */
rc = SQLITE_ERROR;
}
}
if( rc!=SQLITE_OK ){
unicodeDestroy((sqlite3_tokenizer *)pNew);
pNew = 0;
}
*pp = (sqlite3_tokenizer *)pNew;
return rc;
}
/*
** Prepare to begin tokenizing a particular string. The input
** string to be tokenized is pInput[0..nBytes-1]. A cursor
** used to incrementally tokenize this string is returned in
** *ppCursor.
*/
static int unicodeOpen(
sqlite3_tokenizer *p, /* The tokenizer */
const char *aInput, /* Input string */
int nInput, /* Size of string aInput in bytes */
sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */
){
unicode_cursor *pCsr;
pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor));
if( pCsr==0 ){
return SQLITE_NOMEM;
}
memset(pCsr, 0, sizeof(unicode_cursor));
pCsr->aInput = (const unsigned char *)aInput;
if( aInput==0 ){
pCsr->nInput = 0;
}else if( nInput<0 ){
pCsr->nInput = (int)strlen(aInput);
}else{
pCsr->nInput = nInput;
}
*pp = &pCsr->base;
UNUSED_PARAMETER(p);
return SQLITE_OK;
}
/*
** Close a tokenization cursor previously opened by a call to
** simpleOpen() above.
*/
static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){
unicode_cursor *pCsr = (unicode_cursor *) pCursor;
sqlite3_free(pCsr->zToken);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** Extract the next token from a tokenization cursor. The cursor must
** have been opened by a prior call to simpleOpen().
*/
static int unicodeNext(
sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */
const char **paToken, /* OUT: Token text */
int *pnToken, /* OUT: Number of bytes at *paToken */
int *piStart, /* OUT: Starting offset of token */
int *piEnd, /* OUT: Ending offset of token */
int *piPos /* OUT: Position integer of token */
){
unicode_cursor *pCsr = (unicode_cursor *)pC;
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
int iCode;
char *zOut;
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
const unsigned char *zStart = z;
const unsigned char *zEnd;
const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput];
/* Scan past any delimiter characters before the start of the next token.
** Return SQLITE_DONE early if this takes us all the way to the end of
** the input. */
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
if( unicodeIsAlnum(p, iCode) ) break;
zStart = z;
}
if( zStart>=zTerm ) return SQLITE_DONE;
zOut = pCsr->zToken;
do {
int iOut;
/* Grow the output buffer if required. */
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
if( !zNew ) return SQLITE_NOMEM;
zOut = &zNew[zOut - pCsr->zToken];
pCsr->zToken = zNew;
pCsr->nAlloc += 64;
}
/* Write the folded case of the last character read to the output */
zEnd = z;
iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
if( iOut ){
WRITE_UTF8(zOut, iOut);
}
/* If the cursor is not at EOF, read the next character */
if( z>=zTerm ) break;
READ_UTF8(z, zTerm, iCode);
}while( unicodeIsAlnum(p, iCode)
|| sqlite3FtsUnicodeIsdiacritic(iCode)
);
/* Set the output variables and return. */
pCsr->iOff = (z - pCsr->aInput);
*paToken = pCsr->zToken;
*pnToken = zOut - pCsr->zToken;
*piStart = (zStart - pCsr->aInput);
*piEnd = (zEnd - pCsr->aInput);
*piPos = pCsr->iToken++;
return SQLITE_OK;
}
/*
** Set *ppModule to a pointer to the sqlite3_tokenizer_module
** structure for the unicode tokenizer.
*/
SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){
static const sqlite3_tokenizer_module module = {
0,
unicodeCreate,
unicodeDestroy,
unicodeOpen,
unicodeClose,
unicodeNext,
0,
};
*ppModule = &module;
}
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */
/************** End of fts3_unicode.c ****************************************/
/************** Begin file fts3_unicode2.c ***********************************/
/*
** 2012 May 25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
*/
/*
** DO NOT EDIT THIS MACHINE GENERATED FILE.
*/
#if defined(SQLITE_ENABLE_FTS4_UNICODE61)
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
/* #include <assert.h> */
/*
** Return true if the argument corresponds to a unicode codepoint
** classified as either a letter or a number. Otherwise false.
**
** The results are undefined if the value passed to this function
** is less than zero.
*/
SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
/* Each unsigned integer in the following array corresponds to a contiguous
** range of unicode codepoints that are not either letters or numbers (i.e.
** codepoints for which this function should return 0).
**
** The most significant 22 bits in each 32-bit value contain the first
** codepoint in the range. The least significant 10 bits are used to store
** the size of the range (always at least 1). In other words, the value
** ((C<<22) + N) represents a range of N codepoints starting with codepoint
** C. It is not possible to represent a range larger than 1023 codepoints
** using this format.
*/
const static unsigned int aEntry[] = {
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810,
0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023,
0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807,
0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405,
0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E,
0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01,
0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01,
0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016,
0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004,
0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004,
0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5,
0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01,
0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401,
0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064,
0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F,
0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014,
0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001,
0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018,
0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401,
0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001,
0x43FFF401,
};
static const unsigned int aAscii[4] = {
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
if( c<128 ){
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aEntry[iTest] ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( aEntry[0]<key );
assert( key>=aEntry[iRes] );
return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
}
return 1;
}
/*
** If the argument is a codepoint corresponding to a lowercase letter
** in the ASCII range with a diacritic added, return the codepoint
** of the ASCII letter only. For example, if passed 235 - "LATIN
** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
** E"). The resuls of passing a codepoint that corresponds to an
** uppercase letter are undefined.
*/
static int remove_diacritic(int c){
unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
62924, 63050, 63082, 63274, 63390,
};
char aChar[] = {
'\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
'e', 'i', 'o', 'u', 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
int iRes = 0;
int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aDia[iTest] ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
};
/*
** Return true if the argument interpreted as a unicode codepoint
** is a diacritical modifier character.
*/
SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
unsigned int mask0 = 0x08029FDF;
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
return (c < 768+32) ?
(mask0 & (1 << (c-768))) :
(mask1 & (1 << (c-768-32)));
}
/*
** Interpret the argument as a unicode codepoint. If the codepoint
** is an upper case character that has a lower case equivalent,
** return the codepoint corresponding to the lower case version.
** Otherwise, return a copy of the argument.
**
** The results are undefined if the value passed to this function
** is less than zero.
*/
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
**
** If the least significant bit in flags is clear, then the rule applies
** to all nRange codepoints (i.e. all nRange codepoints are upper case and
** need to be folded). Or, if it is set, then the rule only applies to
** every second codepoint in the range, starting with codepoint C.
**
** The 7 most significant bits in flags are an index into the aiOff[]
** array. If a specific codepoint C does require folding, then its lower
** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
**
** The contents of this array are generated by parsing the CaseFolding.txt
** file distributed as part of the "Unicode Character Database". See
** http://www.unicode.org for details.
*/
static const struct TableEntry {
unsigned short iCode;
unsigned char flags;
unsigned char nRange;
} aEntry[] = {
{65, 14, 26}, {181, 64, 1}, {192, 14, 23},
{216, 14, 7}, {256, 1, 48}, {306, 1, 6},
{313, 1, 16}, {330, 1, 46}, {376, 116, 1},
{377, 1, 6}, {383, 104, 1}, {385, 50, 1},
{386, 1, 4}, {390, 44, 1}, {391, 0, 1},
{393, 42, 2}, {395, 0, 1}, {398, 32, 1},
{399, 38, 1}, {400, 40, 1}, {401, 0, 1},
{403, 42, 1}, {404, 46, 1}, {406, 52, 1},
{407, 48, 1}, {408, 0, 1}, {412, 52, 1},
{413, 54, 1}, {415, 56, 1}, {416, 1, 6},
{422, 60, 1}, {423, 0, 1}, {425, 60, 1},
{428, 0, 1}, {430, 60, 1}, {431, 0, 1},
{433, 58, 2}, {435, 1, 4}, {439, 62, 1},
{440, 0, 1}, {444, 0, 1}, {452, 2, 1},
{453, 0, 1}, {455, 2, 1}, {456, 0, 1},
{458, 2, 1}, {459, 1, 18}, {478, 1, 18},
{497, 2, 1}, {498, 1, 4}, {502, 122, 1},
{503, 134, 1}, {504, 1, 40}, {544, 110, 1},
{546, 1, 18}, {570, 70, 1}, {571, 0, 1},
{573, 108, 1}, {574, 68, 1}, {577, 0, 1},
{579, 106, 1}, {580, 28, 1}, {581, 30, 1},
{582, 1, 10}, {837, 36, 1}, {880, 1, 4},
{886, 0, 1}, {902, 18, 1}, {904, 16, 3},
{908, 26, 1}, {910, 24, 2}, {913, 14, 17},
{931, 14, 9}, {962, 0, 1}, {975, 4, 1},
{976, 140, 1}, {977, 142, 1}, {981, 146, 1},
{982, 144, 1}, {984, 1, 24}, {1008, 136, 1},
{1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1},
{1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1},
{1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32},
{1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1},
{1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38},
{4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1},
{7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1},
{7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6},
{7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6},
{8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8},
{8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2},
{8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1},
{8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2},
{8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2},
{8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2},
{8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1},
{8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16},
{8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47},
{11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1},
{11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1},
{11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1},
{11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2},
{11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
{42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14},
{42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1},
{42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1},
{42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1},
{65313, 14, 26},
};
static const unsigned short aiOff[] = {
1, 2, 8, 15, 16, 26, 28, 32,
37, 38, 40, 48, 63, 64, 69, 71,
79, 80, 116, 202, 203, 205, 206, 207,
209, 210, 211, 213, 214, 217, 218, 219,
775, 7264, 10792, 10795, 23228, 23256, 30204, 54721,
54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274,
57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406,
65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462,
65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511,
65514, 65521, 65527, 65528, 65529,
};
int ret = c;
assert( c>=0 );
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
int iRes = -1;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
int cmp = (c - aEntry[iTest].iCode);
if( cmp>=0 ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( iRes<0 || c>=aEntry[iRes].iCode );
if( iRes>=0 ){
const struct TableEntry *p = &aEntry[iRes];
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
assert( ret>0 );
}
}
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
}
else if( c>=66560 && c<66600 ){
ret = c + 40;
}
return ret;
}
#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */
/************** End of fts3_unicode2.c ***************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
|
| ︙ | ︙ | |||
135099 135100 135101 135102 135103 135104 135105 135106 135107 135108 135109 135110 135111 135112 |
rc = nodeRelease(pRtree, pRoot);
}else{
nodeRelease(pRtree, pRoot);
}
return rc;
}
/*
** The xUpdate method for rtree module virtual tables.
*/
static int rtreeUpdate(
sqlite3_vtab *pVtab,
int nData,
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 134504 134505 134506 134507 134508 134509 134510 134511 134512 134513 134514 134515 134516 134517 134518 134519 134520 134521 134522 134523 134524 134525 134526 134527 134528 134529 134530 134531 134532 134533 134534 134535 134536 134537 134538 134539 134540 134541 134542 134543 134544 134545 134546 134547 |
rc = nodeRelease(pRtree, pRoot);
}else{
nodeRelease(pRtree, pRoot);
}
return rc;
}
/*
** Rounding constants for float->double conversion.
*/
#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */
#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */
#if !defined(SQLITE_RTREE_INT_ONLY)
/*
** Convert an sqlite3_value into an RtreeValue (presumably a float)
** while taking care to round toward negative or positive, respectively.
*/
static RtreeValue rtreeValueDown(sqlite3_value *v){
double d = sqlite3_value_double(v);
float f = (float)d;
if( f>d ){
f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS));
}
return f;
}
static RtreeValue rtreeValueUp(sqlite3_value *v){
double d = sqlite3_value_double(v);
float f = (float)d;
if( f<d ){
f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY));
}
return f;
}
#endif /* !defined(SQLITE_RTREE_INT_ONLY) */
/*
** The xUpdate method for rtree module virtual tables.
*/
static int rtreeUpdate(
sqlite3_vtab *pVtab,
int nData,
|
| ︙ | ︙ | |||
135136 135137 135138 135139 135140 135141 135142 |
int ii;
/* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
assert( nData==(pRtree->nDim*2 + 3) );
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
| | | | 134571 134572 134573 134574 134575 134576 134577 134578 134579 134580 134581 134582 134583 134584 134585 134586 |
int ii;
/* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
assert( nData==(pRtree->nDim*2 + 3) );
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
rc = SQLITE_CONSTRAINT;
goto constraint;
}
}
}else
#endif
|
| ︙ | ︙ | |||
136390 136391 136392 136393 136394 136395 136396 |
iEnd = ubrk_next(pCsr->pIter);
if( iEnd==UBRK_DONE ){
return SQLITE_DONE;
}
while( iStart<iEnd ){
int iWhite = iStart;
| | | 135825 135826 135827 135828 135829 135830 135831 135832 135833 135834 135835 135836 135837 135838 135839 |
iEnd = ubrk_next(pCsr->pIter);
if( iEnd==UBRK_DONE ){
return SQLITE_DONE;
}
while( iStart<iEnd ){
int iWhite = iStart;
U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
if( u_isspace(c) ){
iStart = iWhite;
}else{
break;
}
}
assert(iStart<=iEnd);
|
| ︙ | ︙ |
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.14" #define SQLITE_VERSION_NUMBER 3007014 #define SQLITE_SOURCE_ID "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242" /* ** 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 |
| ︙ | ︙ | |||
215 216 217 218 219 220 221 |
** CAPI3REF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite3". It is useful to think of an sqlite3
** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
| > | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
** CAPI3REF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite3". It is useful to think of an sqlite3
** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
** and [sqlite3_close_v2()] are its destructors. There are many other
** interfaces (such as
** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
** [sqlite3_busy_timeout()] to name but three) that are methods on an
** sqlite3 object.
*/
typedef struct sqlite3 sqlite3;
/*
|
| ︙ | ︙ | |||
262 263 264 265 266 267 268 | #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** | > | | | > > > > > > > > > > > > | | > | | | > > | | > | | | > | 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 | #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** ** ^If the database connection is associated with unfinalized prepared ** statements or unfinished sqlite3_backup objects then sqlite3_close() ** will leave the database connection open and return [SQLITE_BUSY]. ** ^If sqlite3_close_v2() is called with unfinalized prepared statements ** and unfinished sqlite3_backups, then the database connection becomes ** an unusable "zombie" which will automatically be deallocated when the ** last prepared statement is finalized or the last sqlite3_backup is ** finished. The sqlite3_close_v2() interface is intended for use with ** host languages that are garbage collected, and where the order in which ** destructors are called is arbitrary. ** ** Applications should [sqlite3_finalize | finalize] all [prepared statements], ** [sqlite3_blob_close | close] all [BLOB handles], and ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated ** with the [sqlite3] object prior to attempting to close the object. ^If ** sqlite3_close() is called on a [database connection] that still has ** outstanding [prepared statements], [BLOB handles], and/or ** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation ** of resources is deferred until all [prepared statements], [BLOB handles], ** and [sqlite3_backup] objects are also destroyed. ** ** ^If an [sqlite3] object is destroyed while a transaction is open, ** the transaction is automatically rolled back. ** ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ SQLITE_API int sqlite3_close(sqlite3*); SQLITE_API int sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ typedef int (*sqlite3_callback)(void*,int,char**, char**); |
| ︙ | ︙ | |||
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ | > > | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ |
| ︙ | ︙ | |||
767 768 769 770 771 772 773 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the | | | 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary ** write ahead log and shared memory files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to |
| ︙ | ︙ | |||
2164 2165 2166 2167 2168 2169 2170 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** | | | | | 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** ** Prior to SQLite version 3.7.10, the Windows OS interface layer called ** the system malloc() and free() directly when converting ** filenames between the UTF-8 encoding used by SQLite ** and whatever filename encoding is used by the particular Windows ** installation. Memory allocation errors were detected, but ** they were reported back as [SQLITE_CANTOPEN] or ** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. ** ** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] ** must be either NULL or else pointers obtained from a prior ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** |
| ︙ | ︙ | |||
2570 2571 2572 2573 2574 2575 2576 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** | | | > | > | | | | 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw", ** "rwc", or "memory". Attempting to set it to any other value is ** an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is ** set to "memory" then a pure [in-memory database] that never reads ** or writes from disk is used. ^It is an error to specify a value for ** the mode parameter that is less restrictive than that specified by ** the flags passed in the third parameter to sqlite3_open_v2(). ** ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| ︙ | ︙ | |||
4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
/*
** CAPI3REF: Name Of The Folder Holding Database Files
**
** ^(If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all database files
** specified with a relative pathname and created or accessed by
** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed
** to be relative to that directory.)^ ^If this variable is a NULL
** pointer, then SQLite assumes that all database files specified
** with a relative pathname are relative to the current directory
** for the process. Only the windows VFS makes use of this global
** variable; it is ignored by the unix VFS.
**
** Changing the value of this variable while a database connection is
** open can result in a corrupt database.
**
** It is not safe to read or modify this variable in more than one
** thread at a time. It is not safe to read or modify this variable
** if a [database connection] is being used at the same time in a separate
** thread.
** It is intended that this variable be set once
** as part of process initialization and before any SQLite interface
** routines have been called and that this variable remain unchanged
** thereafter.
**
** ^The [data_store_directory pragma] may modify this variable and cause
** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
** the [data_store_directory pragma] always assumes that any string
** that this variable points to is held in memory obtained from
** [sqlite3_malloc] and the pragma may attempt to free that memory
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
|
| ︙ | ︙ | |||
4622 4623 4624 4625 4626 4627 4628 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache | < | 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache ** ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** ** ^Cache sharing is enabled and disabled for an entire process. |
| ︙ | ︙ | |||
5450 5451 5452 5453 5454 5455 5456 | ** ** The SQLite source code contains multiple implementations ** of these mutex routines. An appropriate implementation ** is selected automatically at compile-time. ^(The following ** implementations are available in the SQLite core: ** ** <ul> | < | | | | 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 | ** ** The SQLite source code contains multiple implementations ** of these mutex routines. An appropriate implementation ** is selected automatically at compile-time. ^(The following ** implementations are available in the SQLite core: ** ** <ul> ** <li> SQLITE_MUTEX_PTHREADS ** <li> SQLITE_MUTEX_W32 ** <li> SQLITE_MUTEX_NOOP ** </ul>)^ ** ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines ** that does no real locking and is appropriate for use in ** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix ** and Windows. ** ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex ** implementation is included with the library. In this case the ** application must supply a custom mutex implementation using the ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function ** before calling sqlite3_initialize() or any other public sqlite3_ |
| ︙ | ︙ | |||
6010 6011 6012 6013 6014 6015 6016 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect | | | 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 |
| ︙ | ︙ |
Changes to src/stash.c.
| ︙ | ︙ | |||
214 215 216 217 218 219 220 |
if( isNewLink ){
blob_read_link(&disk, zOPath);
}else{
blob_read_from_file(&disk, zOPath);
}
content_get(rid, &a);
blob_delta_apply(&a, &delta, &b);
| | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
if( isNewLink ){
blob_read_link(&disk, zOPath);
}else{
blob_read_from_file(&disk, zOPath);
}
content_get(rid, &a);
blob_delta_apply(&a, &delta, &b);
if( isLink == isNewLink && blob_compare(&disk, &a)==0 ){
if( isLink || isNewLink ){
file_delete(zNPath);
}
if( isLink ){
symlink_create(blob_str(&b), zNPath);
}else{
blob_write_to_file(&b, zNPath);
|
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
110 111 112 113 114 115 116 |
" WHERE +tagname GLOB 'tkt-*'");
@ %d(n)
@ </td></tr>
}
@ <tr><th>Duration Of Project:</th><td>
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
" + 0.99");
| | < < < | < | < < < > | 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 |
" WHERE +tagname GLOB 'tkt-*'");
@ %d(n)
@ </td></tr>
}
@ <tr><th>Duration Of Project:</th><td>
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
" + 0.99");
@ %d(n) days or approximately %.2f(n/356.24) years.
@ </td></tr>
@ <tr><th>Project ID:</th><td>%h(db_get("project-code",""))</td></tr>
@ <tr><th>Server ID:</th><td>%h(db_get("server-code",""))</td></tr>
@ <tr><th>Fossil Version:</th><td>
@ %h(RELEASE_VERSION) %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
@ (%h(COMPILER_NAME))
@ </td></tr>
@ <tr><th>SQLite Version:</th><td>%.19s(SQLITE_SOURCE_ID)
@ [%.10s(&SQLITE_SOURCE_ID[20])] (%s(SQLITE_VERSION))</td></tr>
@ <tr><th>Database Stats:</th><td>
zDb = db_name("repository");
@ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages,
@ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page,
@ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages,
@ %s(db_text(0, "PRAGMA %s.encoding", zDb)),
@ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode
@ </td></tr>
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | static int headerHasBeenGenerated = 0; /* ** remember, if a sidebox was used */ static int sideboxUsed = 0; /* ** Add a new element to the submenu */ void style_submenu_element( const char *zLabel, const char *zTitle, const char *zLink, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
static int headerHasBeenGenerated = 0;
/*
** remember, if a sidebox was used
*/
static int sideboxUsed = 0;
/*
** List of hyperlinks that need to be resolved by javascript in
** the footer.
*/
char **aHref = 0;
int nHref = 0;
int nHrefAlloc = 0;
/*
** Generate and return a anchor tag like this:
**
** <a href="URL">
** or <a id="ID">
**
** The form of the anchor tag is determined by the g.javascriptHyperlink
** variable. The href="URL" form is used if g.javascriptHyperlink is false.
** If g.javascriptHyperlink is true then the
** id="ID" form is used and javascript is generated in the footer to cause
** href values to be inserted after the page has loaded. If
** g.perm.History is false, then the <a id="ID"> form is still
** generated but the javascript is not generated so the links never
** activate.
**
** Filling in the href="URL" using javascript is a defense against bots.
**
** The name of this routine is deliberately kept short so that can be
** easily used within @-lines. Example:
**
** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
**
** Note %z format. The string returned by this function is always
** obtained from fossil_malloc() so rendering it with %z will reclaim
** that memory space.
**
** There are two versions of this routine: href() does a plain hyperlink
** and xhref() adds extra attribute text.
*/
char *xhref(const char *zExtra, const char *zFormat, ...){
char *zUrl;
va_list ap;
va_start(ap, zFormat);
zUrl = vmprintf(zFormat, ap);
va_end(ap);
if( g.perm.Hyperlink && !g.javascriptHyperlink ){
return mprintf("<a %s href=\"%z\">", zExtra, zUrl);
}
if( nHref>=nHrefAlloc ){
nHrefAlloc = nHrefAlloc*2 + 10;
aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
}
aHref[nHref++] = zUrl;
return mprintf("<a %s id=%d>", zExtra, nHref);
}
char *href(const char *zFormat, ...){
char *zUrl;
va_list ap;
va_start(ap, zFormat);
zUrl = vmprintf(zFormat, ap);
va_end(ap);
if( g.perm.Hyperlink && !g.javascriptHyperlink ){
return mprintf("<a href=\"%z\">", zUrl);
}
if( nHref>=nHrefAlloc ){
nHrefAlloc = nHrefAlloc*2 + 10;
aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
}
aHref[nHref++] = zUrl;
return mprintf("<a id=%d>", nHref);
}
/*
** Generate javascript that will set the href= attribute on all anchors.
*/
void style_resolve_href(void){
int i;
if( !g.perm.Hyperlink || !g.javascriptHyperlink || nHref==0 ) return;
@ <script type="text/JavaScript">
@ /* <![CDATA[ */
@ function u(i,h){gebi(i).href=h;}
for(i=0; i<nHref; i++){
@ u(%d(i+1),"%s(aHref[i])");
}
@ /* ]]> */
@ </script>
}
/*
** Add a new element to the submenu
*/
void style_submenu_element(
const char *zLabel,
const char *zTitle,
const char *zLink,
|
| ︙ | ︙ | |||
85 86 87 88 89 90 91 | login_check_credentials(); va_start(ap, zTitleFormat); zTitle = vmprintf(zTitleFormat, ap); va_end(ap); cgi_destination(CGI_HEADER); | > | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
login_check_credentials();
va_start(ap, zTitleFormat);
zTitle = vmprintf(zTitleFormat, ap);
va_end(ap);
cgi_destination(CGI_HEADER);
@ <!DOCTYPE html>
if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);
/* Generate the header up through the main menu */
Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
Th_Store("title", zTitle);
Th_Store("baseurl", g.zBaseURL);
|
| ︙ | ︙ | |||
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
Th_Render(zHeader);
if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1);
Th_Unstore("title"); /* Avoid collisions with ticket field names */
cgi_destination(CGI_BODY);
g.cgiOutput = 1;
headerHasBeenGenerated = 1;
sideboxUsed = 0;
}
/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
const char *zFooter;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
Th_Render(zHeader);
if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1);
Th_Unstore("title"); /* Avoid collisions with ticket field names */
cgi_destination(CGI_BODY);
g.cgiOutput = 1;
headerHasBeenGenerated = 1;
sideboxUsed = 0;
/* Make the gebi(x) function available as an almost-alias for
** document.getElementById(x) (except that it throws if the element is not found).
**
** Maintenance note: this function must of course be available
** before it is called. It "should" go in the HEAD so that client
** HEAD code can make use of it, but because the client can replace
** the HEAD, and some fossil pages rely on gebi(), we put it here.
*/
@ <script>
@ function gebi(x){
@ if(/^#/.test(x)) x = x.substr(1);
@ var e = document.getElementById(x);
@ if(!e) throw new Error("Expecting element with ID "+x);
@ else return e;}
@ </script>
}
/*
** Append ad unit text if appropriate.
*/
static void style_ad_unit(void){
const char *zAd;
if( g.perm.Admin && db_get_boolean("adunit-omit-if-admin",0) ){
return;
}
if( g.zLogin && strcmp(g.zLogin,"anonymous")!=0
&& db_get_boolean("adunit-omit-if-user",0) ){
return;
}
zAd = db_get("adunit", 0);
if( zAd ) cgi_append_content(zAd, -1);
}
/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
const char *zFooter;
|
| ︙ | ︙ | |||
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 |
@ <span class="label">%h(p->zLabel)</span>
}else{
@ <a class="label" href="%s(p->zLink)">%h(p->zLabel)</a>
}
}
@ </div>
}
@ <div class="content">
cgi_destination(CGI_BODY);
if (sideboxUsed) {
/* Put the footer at the bottom of the page.
** the additional clear/both is needed to extend the content
** part to the end of an optional sidebox.
*/
@ <div class="endContent"></div>
}
@ </div>
zFooter = db_get("footer", (char*)zDefaultFooter);
if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
Th_Render(zFooter);
if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
/* Render trace log if TH1 tracing is enabled. */
if( g.thTrace ){
| > > > > > > | 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 |
@ <span class="label">%h(p->zLabel)</span>
}else{
@ <a class="label" href="%s(p->zLink)">%h(p->zLabel)</a>
}
}
@ </div>
}
style_ad_unit();
@ <div class="content">
cgi_destination(CGI_BODY);
if (sideboxUsed) {
/* Put the footer at the bottom of the page.
** the additional clear/both is needed to extend the content
** part to the end of an optional sidebox.
*/
@ <div class="endContent"></div>
}
@ </div>
/* Set the href= field on hyperlinks. Do this before the footer since
** the footer will be generating </html> */
style_resolve_href();
zFooter = db_get("footer", (char*)zDefaultFooter);
if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
Th_Render(zFooter);
if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
/* Render trace log if TH1 tracing is enabled. */
if( g.thTrace ){
|
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
41 42 43 44 45 46 47 |
){
PQueue queue; /* Queue of check-ins to be tagged */
Stmt s; /* Query the children of :pid to which to propagate */
Stmt ins; /* INSERT INTO tagxref */
Stmt eventupdate; /* UPDATE event */
assert( tagType==0 || tagType==2 );
| | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
){
PQueue queue; /* Queue of check-ins to be tagged */
Stmt s; /* Query the children of :pid to which to propagate */
Stmt ins; /* INSERT INTO tagxref */
Stmt eventupdate; /* UPDATE event */
assert( tagType==0 || tagType==2 );
pqueuex_init(&queue);
pqueuex_insert(&queue, pid, 0.0, 0);
/* Query for children of :pid to which to propagate the tag.
** Three returns: (1) rid of the child. (2) timestamp of child.
** (3) True to propagate or false to block.
*/
db_prepare(&s,
"SELECT cid, plink.mtime,"
|
| ︙ | ︙ | |||
77 78 79 80 81 82 83 |
);
}
if( tagid==TAG_BGCOLOR ){
db_prepare(&eventupdate,
"UPDATE event SET bgcolor=%Q WHERE objid=:rid", zValue
);
}
| | | | | 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 |
);
}
if( tagid==TAG_BGCOLOR ){
db_prepare(&eventupdate,
"UPDATE event SET bgcolor=%Q WHERE objid=:rid", zValue
);
}
while( (pid = pqueuex_extract(&queue, 0))!=0 ){
db_bind_int(&s, ":pid", pid);
while( db_step(&s)==SQLITE_ROW ){
int doit = db_column_int(&s, 2);
if( doit ){
int cid = db_column_int(&s, 0);
double mtime = db_column_double(&s, 1);
pqueuex_insert(&queue, cid, mtime, 0);
db_bind_int(&ins, ":rid", cid);
db_step(&ins);
db_reset(&ins);
if( tagid==TAG_BGCOLOR ){
db_bind_int(&eventupdate, ":rid", cid);
db_step(&eventupdate);
db_reset(&eventupdate);
}
if( tagid==TAG_BRANCH ){
leaf_eventually_check(cid);
}
}
}
db_reset(&s);
}
pqueuex_clear(&queue);
db_finalize(&ins);
db_finalize(&s);
if( tagid==TAG_BGCOLOR ){
db_finalize(&eventupdate);
}
}
|
| ︙ | ︙ | |||
546 547 548 549 550 551 552 |
" AND tagtype=1)"
" AND tagname GLOB 'sym-*'"
" ORDER BY tagname"
);
@ <ul>
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
| | | | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
" AND tagtype=1)"
" AND tagname GLOB 'sym-*'"
" ORDER BY tagname"
);
@ <ul>
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
if( g.perm.Hyperlink ){
@ <li>%z(xhref("class='taglink'","%R/timeline?t=%T",zName))
@ %h(zName)</a></li>
}else{
@ <li><span class="tagDsp">%h(zName)</span></li>
}
}
@ </ul>
db_finalize(&q);
|
| ︙ | ︙ |
Changes to src/tar.c.
| ︙ | ︙ | |||
579 580 581 582 583 584 585 |
int nName, nRid;
Blob tarball;
login_check_credentials();
if( !g.perm.Zip ){ login_needed(); return; }
zName = mprintf("%s", PD("name",""));
nName = strlen(zName);
| | | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
int nName, nRid;
Blob tarball;
login_check_credentials();
if( !g.perm.Zip ){ login_needed(); return; }
zName = mprintf("%s", PD("name",""));
nName = strlen(zName);
zRid = mprintf("%s", PD("uuid","trunk"));
nRid = strlen(zRid);
if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){
/* Special case: Remove the ".tar.gz" suffix. */
nName -= 7;
zName[nName] = 0;
}else{
/* If the file suffix is not ".tar.gz" then just remove the
|
| ︙ | ︙ |
Changes to src/th_lang.c.
| ︙ | ︙ | |||
356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
if( p->hasArgs ){
char *zArgs = 0;
int nArgs = 0;
for(i=p->nParam+1; i<pArgs->argc; i++){
Th_ListAppend(interp, &zArgs, &nArgs, pArgs->argv[i], pArgs->argl[i]);
}
Th_SetVar(interp, (const char *)"args", -1, zArgs, nArgs);
}
Th_SetResult(interp, 0, 0);
return Th_Eval(interp, 0, p->zProgram, p->nProgram);
}
/*
| > > > | 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
if( p->hasArgs ){
char *zArgs = 0;
int nArgs = 0;
for(i=p->nParam+1; i<pArgs->argc; i++){
Th_ListAppend(interp, &zArgs, &nArgs, pArgs->argv[i], pArgs->argl[i]);
}
Th_SetVar(interp, (const char *)"args", -1, zArgs, nArgs);
if(zArgs){
Th_Free(interp, zArgs);
}
}
Th_SetResult(interp, 0, 0);
return Th_Eval(interp, 0, p->zProgram, p->nProgram);
}
/*
|
| ︙ | ︙ |
Changes to src/th_main.c.
| ︙ | ︙ | |||
212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
rc = login_has_capability((char*)argv[1],argl[1]);
if( g.thTrace ){
Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc);
}
Th_SetResultInt(interp, rc);
return TH_OK;
}
/*
** TH command: anycap STRING
**
** Return true if the user has any one of the capabilities listed in STRING.
*/
static int anycapCmd(
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
rc = login_has_capability((char*)argv[1],argl[1]);
if( g.thTrace ){
Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc);
}
Th_SetResultInt(interp, rc);
return TH_OK;
}
/*
** TH command: hasfeature STRING
**
** Return true if the fossil binary has the given compile-time feature
** enabled. The set of features includes:
**
** "json" = FOSSIL_ENABLE_JSON
** "tcl" = FOSSIL_ENABLE_TCL
** "ssl" = FOSSIL_ENABLE_SSL
**
*/
static int hasfeatureCmd(
Th_Interp *interp,
void *p,
int argc,
const char **argv,
int *argl
){
int rc = 0;
char const * zArg;
if( argc!=2 ){
return Th_WrongNumArgs(interp, "hasfeature STRING");
}
zArg = (char const*)argv[1];
if(NULL==zArg){
/* placeholder for following ifdefs... */
}
#if defined(FOSSIL_ENABLE_JSON)
else if( 0 == fossil_strnicmp( zArg, "json", 4 ) ){
rc = 1;
}
#endif
#if defined(FOSSIL_ENABLE_SSL)
else if( 0 == fossil_strnicmp( zArg, "ssl", 3 ) ){
rc = 1;
}
#endif
#if defined(FOSSIL_ENABLE_TCL)
else if( 0 == fossil_strnicmp( zArg, "tcl", 3 ) ){
rc = 1;
}
#endif
if( g.thTrace ){
Th_Trace("[hasfeature %#h] => %d<br />\n", argl[1], zArg, rc);
}
Th_SetResultInt(interp, rc);
return TH_OK;
}
/*
** TH command: anycap STRING
**
** Return true if the user has any one of the capabilities listed in STRING.
*/
static int anycapCmd(
|
| ︙ | ︙ | |||
380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
void *pContext;
} aCommand[] = {
{"anycap", anycapCmd, 0},
{"combobox", comboboxCmd, 0},
{"enable_output", enableOutputCmd, 0},
{"linecount", linecntCmd, 0},
{"hascap", hascapCmd, 0},
{"htmlize", htmlizeCmd, 0},
{"date", dateCmd, 0},
{"html", putsCmd, 0},
{"puts", putsCmd, (void*)1},
{"wiki", wikiCmd, 0},
{"repository", repositoryCmd, 0},
{0, 0, 0}
| > | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
void *pContext;
} aCommand[] = {
{"anycap", anycapCmd, 0},
{"combobox", comboboxCmd, 0},
{"enable_output", enableOutputCmd, 0},
{"linecount", linecntCmd, 0},
{"hascap", hascapCmd, 0},
{"hasfeature", hasfeatureCmd, 0},
{"htmlize", htmlizeCmd, 0},
{"date", dateCmd, 0},
{"html", putsCmd, 0},
{"puts", putsCmd, (void*)1},
{"wiki", wikiCmd, 0},
{"repository", repositoryCmd, 0},
{0, 0, 0}
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 |
/*
** Generate a hyperlink to a version.
*/
void hyperlink_to_uuid(const char *zUuid){
char z[UUID_SIZE+1];
shorten_uuid(z, zUuid);
| | | | | | | | | | | | 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 |
/*
** Generate a hyperlink to a version.
*/
void hyperlink_to_uuid(const char *zUuid){
char z[UUID_SIZE+1];
shorten_uuid(z, zUuid);
if( g.perm.Hyperlink ){
@ %z(xhref("class='timelineHistLink'","%R/info/%s",z))[%s(z)]</a>
}else{
@ <span class="timelineHistDsp">[%s(z)]</span>
}
}
/*
** Generate a hyperlink to a diff between two versions.
*/
void hyperlink_to_diff(const char *zV1, const char *zV2){
if( g.perm.Hyperlink ){
if( zV2==0 ){
@ %z(href("%R/diff?v2=%s",zV1))[diff]</a>
}else{
@ %z(href("%R/diff?v1=%s&v2=%s",zV1,zV2))[diff]</a>
}
}
}
/*
** Generate a hyperlink to a date & time.
*/
void hyperlink_to_date(const char *zDate, const char *zSuffix){
if( zSuffix==0 ) zSuffix = "";
if( g.perm.Hyperlink ){
@ %z(href("%R/timeline?c=%T",zDate))%s(zDate)</a>%s(zSuffix)
}else{
@ %s(zDate)%s(zSuffix)
}
}
/*
** Generate a hyperlink to a user. This will link to a timeline showing
** events by that user. If the date+time is specified, then the timeline
** is centered on that date+time.
*/
void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
if( zSuf==0 ) zSuf = "";
if( g.perm.Hyperlink ){
if( zD && zD[0] ){
@ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf)
}else{
@ %z(href("%R/timeline?u=%T",zU))%h(zU)</a>%s(zSuf)
}
}else{
@ %s(zU)
}
}
/*
|
| ︙ | ︙ | |||
206 207 208 209 210 211 212 |
mxWikiLen = db_get_int("timeline-max-comment", 0);
if( db_get_boolean("timeline-block-markup", 0) ){
wikiFlags = WIKI_INLINE;
}else{
wikiFlags = WIKI_INLINE | WIKI_NOBLOCK;
}
zDiffTarget = db_get_boolean("href-targets", 1) ?
| | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
mxWikiLen = db_get_int("timeline-max-comment", 0);
if( db_get_boolean("timeline-block-markup", 0) ){
wikiFlags = WIKI_INLINE;
}else{
wikiFlags = WIKI_INLINE | WIKI_NOBLOCK;
}
zDiffTarget = db_get_boolean("href-targets", 1) ?
"target='diffwindow'": "";
if( tmFlags & TIMELINE_GRAPH ){
pGraph = graph_init();
/* style is not moved to css, because this is
** a technical div for the timeline graph
*/
@ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
}
|
| ︙ | ︙ | |||
350 351 352 353 354 355 356 |
}
blob_reset(&comment);
/* Generate the "user: USERNAME" at the end of the comment, together
** with a hyperlink to another timeline for that user.
*/
if( zTagList && zTagList[0]==0 ) zTagList = 0;
| | | < | < | | | | | | 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 |
}
blob_reset(&comment);
/* Generate the "user: USERNAME" at the end of the comment, together
** with a hyperlink to another timeline for that user.
*/
if( zTagList && zTagList[0]==0 ) zTagList = 0;
if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){
char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate);
@ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051")
}else{
@ (user: %h(zUser)%s(zTagList?",":"\051")
}
/* Generate a "detail" link for tags. */
if( zType[0]=='g' && g.perm.Hyperlink ){
@ [%z(href("%R/info/%S",zUuid))details</a>]
}
/* Generate the "tags: TAGLIST" at the end of the comment, together
** with hyperlinks to the tag list.
*/
if( zTagList ){
if( g.perm.Hyperlink ){
int i;
const char *z = zTagList;
Blob links;
blob_zero(&links);
while( z && z[0] ){
for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
blob_appendf(&links,
"%z%#h</a>%.2s",
href("%R/timeline?r=%#t&nd&c=%s",i,z,zDate), i,z, &z[i]
);
}else{
blob_appendf(&links, "%#h", i+2, z);
}
if( z[i]==0 ) break;
z += i+2;
}
|
| ︙ | ︙ | |||
400 401 402 403 404 405 406 |
/* Generate extra hyperlinks at the end of the comment */
if( xExtra ){
xExtra(rid);
}
/* Generate the file-change list if requested */
| | | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
/* Generate extra hyperlinks at the end of the comment */
if( xExtra ){
xExtra(rid);
}
/* Generate the file-change list if requested */
if( (tmFlags & TIMELINE_FCHANGES)!=0 && zType[0]=='c' && g.perm.Hyperlink ){
int inUl = 0;
if( !fchngQueryInit ){
db_prepare(&fchngQuery,
"SELECT (pid==0) AS isnew,"
" (fid==0) AS isdel,"
" (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
" (SELECT uuid FROM blob WHERE rid=fid),"
|
| ︙ | ︙ | |||
430 431 432 433 434 435 436 |
const char *zNew = db_column_text(&fchngQuery, 3);
if( !inUl ){
@ <ul class="filelist">
inUl = 1;
}
if( isNew ){
@ <li> %h(zFilename) (new file)
| | | | | | | | 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 |
const char *zNew = db_column_text(&fchngQuery, 3);
if( !inUl ){
@ <ul class="filelist">
inUl = 1;
}
if( isNew ){
@ <li> %h(zFilename) (new file)
@ %z(xhref(zDiffTarget,"%R/artifact/%S",zNew))
@ [view]</a></li>
}else if( isDel ){
@ <li> %h(zFilename) (deleted)</li>
}else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
@ <li> %h(zOldName) → %h(zFilename)
@ %z(xhref(zDiffTarget,"%R/artifact/%S",zNew))
@ [view]</a></li>
}else{
if( zOldName!=0 ){
@ <li> %h(zOldName) → %h(zFilename)
}else{
@ <li> %h(zFilename)
}
@ %z(xhref(zDiffTarget,"%R/fdiff?v1=%S&v2=%S",zOld,zNew))
@ [diff]</a></li>
}
}
db_reset(&fchngQuery);
if( inUl ){
@ </ul>
}
}
|
| ︙ | ︙ | |||
566 567 568 569 570 571 572 |
}
}
if( cSep=='[' ) cgi_printf("[");
cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n");
}
cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
graph_free(pGraph);
| | | | | 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 |
}
}
if( cSep=='[' ) cgi_printf("[");
cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n");
}
cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
graph_free(pGraph);
@ var canvasDiv = gebi("canvas");
#if 0
@ var realCanvas = null;
#endif
@ function drawBox(color,x0,y0,x1,y1){
@ var n = document.createElement("div");
@ if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
@ if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
@ var w = x1-x0+1;
@ var h = y1-y0+1;
@ n.style.position = "absolute";
@ n.style.overflow = "hidden";
@ n.style.left = x0+"px";
@ n.style.top = y0+"px";
@ n.style.width = w+"px";
@ n.style.height = h+"px";
@ n.style.backgroundColor = color;
@ canvasDiv.appendChild(n);
@ }
@ function absoluteY(id){
@ var obj = gebi(id);
@ if( !obj ) return;
@ var top = 0;
@ if( obj.offsetParent ){
@ do{
@ top += obj.offsetTop;
@ }while( obj = obj.offsetParent );
@ }
@ return top;
@ }
@ function absoluteX(id){
@ var obj = gebi(id);
@ if( !obj ) return;
@ var left = 0;
@ if( obj.offsetParent ){
@ do{
@ left += obj.offsetLeft;
@ }while( obj = obj.offsetParent );
@ }
|
| ︙ | ︙ | |||
686 687 688 689 690 691 692 |
@ drawThinArrow(y0,mx,p.x+6);
@ }else{
@ drawThinArrow(y0,mx,p.x-5);
@ }
@ }
@ }
@ function renderGraph(){
| | | | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 |
@ drawThinArrow(y0,mx,p.x+6);
@ }else{
@ drawThinArrow(y0,mx,p.x-5);
@ }
@ }
@ }
@ function renderGraph(){
@ var canvasDiv = gebi("canvas");
@ while( canvasDiv.hasChildNodes() ){
@ canvasDiv.removeChild(canvasDiv.firstChild);
@ }
@ var canvasY = absoluteY("timelineTable");
@ var left = absoluteX("m"+rowinfo[0].id) - absoluteX("canvas") + 15;
@ var width = nrail*20;
@ for(var i in rowinfo){
@ rowinfo[i].y = absoluteY("m"+rowinfo[i].id) + 10 - canvasY;
@ rowinfo[i].x = left + rowinfo[i].r*20;
@ }
@ var btm = absoluteY("grbtm") + 10 - canvasY;
#if 0
@ if( btm<32768 ){
@ canvasDiv.innerHTML = '<canvas id="timeline-canvas" '+
@ 'style="position:absolute;left:'+(left-5)+'px;"' +
@ ' width="'+width+'" height="'+btm+'"><'+'/canvas>';
@ realCanvas = gebi('timeline-canvas');
@ }else{
@ realCanvas = 0;
@ }
@ var context;
@ if( realCanvas && realCanvas.getContext
@ && (context = realCanvas.getContext('2d'))) {
@ drawBox = function(color,x0,y0,x1,y1) {
|
| ︙ | ︙ | |||
971 972 973 974 975 976 977 |
while( p ){
blob_appendf(&sql, ",%d", p->rid);
p = p->u.pTo;
}
blob_append(&sql, ")", -1);
path_reset();
blob_append(&desc, "All nodes on the path from ", -1);
| < < < | < < < < | < | 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 |
while( p ){
blob_appendf(&sql, ",%d", p->rid);
p = p->u.pTo;
}
blob_append(&sql, ")", -1);
path_reset();
blob_append(&desc, "All nodes on the path from ", -1);
blob_appendf(&desc, "%z%h</a>", href("%R/info/%h", zFrom), zFrom);
blob_append(&desc, " and ", -1);
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
tmFlags |= TIMELINE_DISJOINT;
db_multi_exec("%s", blob_str(&sql));
}else if( (p_rid || d_rid) && g.perm.Read ){
/* If p= or d= is present, ignore all other parameters other than n= */
char *zUuid;
int np, nd;
|
| ︙ | ︙ | |||
1018 1019 1020 1021 1022 1023 1024 |
if( np>0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestors", np);
db_multi_exec("%s", blob_str(&sql));
}
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
}
| < | | < < < < < < < | < | 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 |
if( np>0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestors", np);
db_multi_exec("%s", blob_str(&sql));
}
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
}
blob_appendf(&desc, " of %z[%.10s]</a>",
href("%R/info/%s", zUuid), zUuid);
}else if( f_rid && g.perm.Read ){
/* If f= is present, ignore all other parameters other than n= */
char *zUuid;
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
"INSERT INTO ok VALUES(%d);"
"INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
"INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
f_rid, f_rid, f_rid
);
blob_appendf(&sql, " AND event.objid IN ok");
db_multi_exec("%s", blob_str(&sql));
if( useDividers ) timeline_add_dividers(0, f_rid);
blob_appendf(&desc, "Parents and children of check-in ");
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid);
}else{
/* Otherwise, a timeline based on a span of time */
int n;
const char *zEType = "timeline item";
char *zDate;
char *zNEntry = mprintf("%d", nEntry);
url_add_parameter(&url, "n", zNEntry);
|
| ︙ | ︙ | |||
1216 1217 1218 1219 1220 1221 1222 |
blob_appendf(&desc, " occurring on or before %h.<br />", zBefore);
}else if( zCirca ){
blob_appendf(&desc, " occurring around %h.<br />", zCirca);
}
if( zSearch ){
blob_appendf(&desc, " matching \"%h\"", zSearch);
}
| | | 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 |
blob_appendf(&desc, " occurring on or before %h.<br />", zBefore);
}else if( zCirca ){
blob_appendf(&desc, " occurring around %h.<br />", zCirca);
}
if( zSearch ){
blob_appendf(&desc, " matching \"%h\"", zSearch);
}
if( g.perm.Hyperlink ){
if( zAfter || n==nEntry ){
zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/");
timeline_submenu(&url, "Older", "b", zDate, "a");
free(zDate);
}
if( zBefore || (zAfter && n==nEntry) ){
zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
|
| ︙ | ︙ | |||
1620 1621 1622 1623 1624 1625 1626 |
/*
** WEBPAGE: test_timewarps
*/
void test_timewarp_page(void){
Stmt q;
login_check_credentials();
| | | | 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 |
/*
** WEBPAGE: test_timewarps
*/
void test_timewarp_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read || !g.perm.Hyperlink ){ login_needed(); return; }
style_header("Instances of timewarp");
@ <ul>
db_prepare(&q,
"SELECT blob.uuid "
" FROM plink p, plink c, blob"
" WHERE p.cid=c.pid AND p.mtime>c.mtime"
" AND blob.rid=c.cid"
);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
@ <li>
@ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)">%S(zUuid)</a>
}
db_finalize(&q);
style_footer();
}
|
Changes to src/tkt.c.
| ︙ | ︙ | |||
303 304 305 306 307 308 309 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
if( g.perm.WrTkt || g.perm.ApndTkt ){
style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T",
g.zTop, PD("name",""));
}
| | | | 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 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
if( g.perm.WrTkt || g.perm.ApndTkt ){
style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T",
g.zTop, PD("name",""));
}
if( g.perm.Hyperlink ){
style_submenu_element("History", "History Of This Ticket",
"%s/tkthistory/%T", g.zTop, zUuid);
style_submenu_element("Timeline", "Timeline Of This Ticket",
"%s/tkttimeline/%T", g.zTop, zUuid);
style_submenu_element("Check-ins", "Check-ins Of This Ticket",
"%s/tkttimeline/%T?y=ci", g.zTop, zUuid);
}
if( g.perm.NewTkt ){
style_submenu_element("New Ticket", "Create a new ticket",
"%s/tktnew", g.zTop);
}
if( g.perm.ApndTkt && g.perm.Attach ){
style_submenu_element("Attach", "Add An Attachment",
"%s/attachadd?tkt=%T&from=%s/tktview/%t",
g.zTop, zUuid, g.zTop, zUuid);
}
style_header("View Ticket");
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
ticket_init();
initializeVariablesFromDb();
zScript = ticket_viewpage_code();
|
| ︙ | ︙ | |||
351 352 353 354 355 356 357 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
| | | | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
if( g.perm.Read && g.perm.Hyperlink ){
@ %z(href("%R/attachview?tkt=%s&file=%t",zFullName,zFile))
@ %h(zFile)</a>
}else{
@ %h(zFile)
}
@ added by %h(zUser) on
hyperlink_to_date(zDate, ".");
if( g.perm.WrTkt && g.perm.Attach ){
@ [%z(href("%R/attachdelete?tkt=%s&file=%t&from=%R/tktview%%3fname=%s",zFullName,zFile,zFullName))delete</a>]
}
@ </li>
}
if( cnt ){
@ </ul>
}
db_finalize(&q);
|
| ︙ | ︙ | |||
645 646 647 648 649 650 651 |
}
}
return 0;
}
/*
** WEBPAGE: tkttimeline
| | | | | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
}
}
return 0;
}
/*
** WEBPAGE: tkttimeline
** URL: /tkttimeline?name=TICKETUUID&y=TYPE
**
** Show the change history for a single ticket in timeline format.
*/
void tkttimeline_page(void){
Stmt q;
char *zTitle;
char *zSQL;
const char *zUuid;
char *zFullUuid;
int tagid;
char zGlobPattern[50];
const char *zType;
login_check_credentials();
if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
zUuid = PD("name","");
zType = PD("y","a");
if( zType[0]!='c' ){
style_submenu_element("Check-ins", "Check-ins",
"%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid);
}else{
style_submenu_element("Timeline", "Timeline",
"%s/tkttimeline?name=%T", g.zTop, zUuid);
}
style_submenu_element("History", "History",
"%s/tkthistory/%s", g.zTop, zUuid);
style_submenu_element("Status", "Status",
|
| ︙ | ︙ | |||
734 735 736 737 738 739 740 |
void tkthistory_page(void){
Stmt q;
char *zTitle;
const char *zUuid;
int tagid;
login_check_credentials();
| | | | 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 |
void tkthistory_page(void){
Stmt q;
char *zTitle;
const char *zUuid;
int tagid;
login_check_credentials();
if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
zUuid = PD("name","");
zTitle = mprintf("History Of Ticket %h", zUuid);
style_submenu_element("Status", "Status",
"%s/info/%s", g.zTop, zUuid);
style_submenu_element("Check-ins", "Check-ins",
"%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid);
style_submenu_element("Timeline", "Timeline",
"%s/tkttimeline?name=%s", g.zTop, zUuid);
style_header(zTitle);
free(zTitle);
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
if( tagid==0 ){
|
| ︙ | ︙ | |||
784 785 786 787 788 789 790 |
if( zSrc==0 || zSrc[0]==0 ){
@
@ <p>Delete attachment "%h(zFile)"
}else{
@
@ <p>Add attachment "%h(zFile)"
}
| | | | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 |
if( zSrc==0 || zSrc[0]==0 ){
@
@ <p>Delete attachment "%h(zFile)"
}else{
@
@ <p>Add attachment "%h(zFile)"
}
@ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
@ (rid %d(rid)) by
hyperlink_to_user(zUser,zDate," on");
hyperlink_to_date(zDate, ".</p>");
}else{
pTicket = manifest_get(rid, CFTYPE_TICKET);
if( pTicket ){
@
@ <p>Ticket change
@ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
@ (rid %d(rid)) by
hyperlink_to_user(pTicket->zUser,zDate," on");
hyperlink_to_date(zDate, ":");
@ </p>
ticket_output_change_artifact(pTicket);
}
manifest_destroy(pTicket);
|
| ︙ | ︙ | |||
853 854 855 856 857 858 859 | /* ** COMMAND: ticket* ** Usage: %fossil ticket SUBCOMMAND ... ** ** Run various subcommands to control tickets ** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | > | > | | | | | | | | | > > > > > > > > > > > > > > | | < > | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < | < < | | | | | | | | | | | | | | | | | | | | < < | < | | | | | | | | | | | | | | < | 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 |
/*
** COMMAND: ticket*
** Usage: %fossil ticket SUBCOMMAND ...
**
** Run various subcommands to control tickets
**
** %fossil ticket show (REPORTTITLE|REPORTNR) ?TICKETFILTER? ?options?
**
** options can be:
** ?-l|--limit LIMITCHAR?
** ?-q|--quote?
** ?-R|--repository FILE?
**
** Run the ticket report, identified by the report format title
** used in the gui. The data is written as flat file on stdout,
** using "," as separator. The separator "," can be changed using
** the -l or --limit option.
**
** If TICKETFILTER is given on the commandline, the query is
** limited with a new WHERE-condition.
** example: Report lists a column # with the uuid
** TICKETFILTER may be [#]='uuuuuuuuu'
** example: Report only lists rows with status not open
** TICKETFILTER: status != 'open'
** If the option -q|--quote is used, the tickets are encoded by
** quoting special chars(space -> \\s, tab -> \\t, newline -> \\n,
** cr -> \\r, formfeed -> \\f, vtab -> \\v, nul -> \\0, \\ -> \\\\).
** Otherwise, the simplified encoding as on the show report raw
** page in the gui is used. This has no effect in JSON mode.
**
** Instead of the report title its possible to use the report
** number. Using the special report number 0 list all columns,
** defined in the ticket table.
**
** %fossil ticket list fields
**
** list all fields, defined for ticket in the fossil repository
**
** %fossil ticket list reports
**
** list all ticket reports, defined in the fossil repository
**
** %fossil ticket set TICKETUUID (FIELD VALUE)+ ?-q|--quote?
** %fossil ticket change TICKETUUID (FIELD VALUE)+ ?-q|--quote?
**
** change ticket identified by TICKETUUID and set the value of
** field FIELD to VALUE.
**
** Field names as defined in the TICKET table. By default, these
** names include: type, status, subsystem, priority, severity, foundin,
** resolution, title, and comment, but other field names can be added
** or substituted in customized installations.
**
** If you use +FIELD, the VALUE Is appended to the field FIELD.
** You can use more than one field/value pair on the commandline.
** Using -q|--quote enables the special character decoding as
** in "ticket show". So it's possible, to set multiline text or
** text with special characters.
**
** %fossil ticket add FIELD VALUE ?FIELD VALUE .. ? ?-q|--quote?
**
** like set, but create a new ticket with the given values.
**
** %fossil ticket history TICKETUUID
**
** Show the complete change history for the ticket
**
** The values in set|add are not validated against the definitions
** given in "Ticket Common Script".
*/
void ticket_cmd(void){
int n;
const char *zUser;
const char *zDate;
const char *zTktUuid;
/* do some ints, we want to be inside a checkout */
db_find_and_open_repository(0, 0);
user_select();
zUser = find_option("user-override",0,1);
if( zUser==0 ) zUser = g.zLogin;
zDate = find_option("date-override",0,1);
if( zDate==0 ) zDate = "now";
zDate = date_in_standard_format(zDate);
zTktUuid = find_option("uuid-override",0,1);
if( zTktUuid && (strlen(zTktUuid)!=40 || !validate16(zTktUuid,40)) ){
fossil_fatal("invalid --uuid-override: must be 40 characters of hex");
}
/*
** Check that the user exists.
*/
if( !db_exists("SELECT 1 FROM user WHERE login=%Q", zUser) ){
fossil_fatal("no such user: %s", zUser);
}
if( g.argc<3 ){
usage("add|fieldlist|set|show|history");
}
n = strlen(g.argv[2]);
if( n==1 && g.argv[2][0]=='s' ){
/* set/show cannot be distinguished, so show the usage */
usage("add|fieldlist|set|show|history");
}
if( strncmp(g.argv[2],"list",n)==0 ){
if( g.argc==3 ){
usage("list fields|reports");
}else{
n = strlen(g.argv[3]);
if( !strncmp(g.argv[3],"fields",n) ){
/* simply show all field names */
int i;
/* read all available ticket fields */
getAllTicketFields();
for(i=0; i<nField; i++){
printf("%s\n",azField[i]);
}
}else if( !strncmp(g.argv[3],"reports",n) ){
rpt_list_reports();
}else{
fossil_fatal("unknown ticket list option '%s'!",g.argv[3]);
}
}
}else{
/* add a new ticket or set fields on existing tickets */
tTktShowEncoding tktEncoding;
tktEncoding = find_option("quote","q",0) ? tktFossilize : tktNoTab;
if( strncmp(g.argv[2],"show",n)==0 ){
if( g.argc==3 ){
usage("show REPORTNR");
}else{
const char *zRep = 0;
const char *zSep = 0;
const char *zFilterUuid = 0;
zSep = find_option("limit","l",1);
zRep = g.argv[3];
if( !strcmp(zRep,"0") ){
zRep = 0;
}
if( g.argc>4 ){
zFilterUuid = g.argv[4];
}
rptshow( zRep, zSep, zFilterUuid, tktEncoding );
}
}else{
/* add a new ticket or update an existing ticket */
enum { set,add,history,err } eCmd = err;
int i = 0;
int rid;
Blob tktchng, cksum;
/* get command type (set/add) and get uuid, if needed for set */
if( strncmp(g.argv[2],"set",n)==0 || strncmp(g.argv[2],"change",n)==0 ||
strncmp(g.argv[2],"history",n)==0 ){
if( strncmp(g.argv[2],"history",n)==0 ){
eCmd = history;
}else{
eCmd = set;
}
if( g.argc==3 ){
usage("set TICKETUUID");
}
zTktUuid = db_text(0,
"SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3]
);
if( !zTktUuid ){
fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
}
i=4;
}else if( strncmp(g.argv[2],"add",n)==0 ){
eCmd = add;
i = 3;
if( zTktUuid==0 ){
zTktUuid = db_text(0, "SELECT lower(hex(randomblob(20)))");
}
}
/* none of set/add, so show the usage! */
if( eCmd==err ){
usage("add|fieldlist|set|show|history");
}
/* we just handle history separately here, does not get out */
if( eCmd==history ){
Stmt q;
int tagid;
if ( i != g.argc ){
fossil_fatal("no other parameters expected to %s!",g.argv[2]);
}
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zTktUuid);
if( tagid==0 ){
fossil_fatal("no such ticket %h", zTktUuid);
}
db_prepare(&q,
"SELECT datetime(mtime,'localtime'), objid, uuid, NULL, NULL, NULL"
" FROM event, blob"
" WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)"
" AND blob.rid=event.objid"
" UNION "
"SELECT datetime(mtime,'localtime'), attachid, uuid, src, filename, user"
" FROM attachment, blob"
" WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
" AND blob.rid=attachid"
" ORDER BY 1 DESC",
tagid, tagid
);
while( db_step(&q)==SQLITE_ROW ){
Manifest *pTicket;
char zShort[12];
const char *zDate = db_column_text(&q, 0);
int rid = db_column_int(&q, 1);
const char *zChngUuid = db_column_text(&q, 2);
const char *zFile = db_column_text(&q, 4);
memcpy(zShort, zChngUuid, 10);
zShort[10] = 0;
if( zFile!=0 ){
const char *zSrc = db_column_text(&q, 3);
const char *zUser = db_column_text(&q, 5);
if( zSrc==0 || zSrc[0]==0 ){
fossil_print("Delete attachment %h\n", zFile);
}else{
fossil_print("Add attachment %h\n", zFile);
}
fossil_print(" by %h on %h\n", zUser, zDate);
}else{
pTicket = manifest_get(rid, CFTYPE_TICKET);
if( pTicket ){
int i;
fossil_print("Ticket Change by %h on %h:\n", pTicket->zUser, zDate);
for(i=0; i<pTicket->nField; i++){
Blob val;
const char *z;
z = pTicket->aField[i].zName;
blob_set(&val, pTicket->aField[i].zValue);
if( z[0]=='+' ){
fossil_print(" Append to ");
z++;
}else{
fossil_print(" Change ");
}
fossil_print("%h: ",z);
if( blob_size(&val)>50 || contains_newline(&val)) {
fossil_print("\n ",blob_str(&val));
comment_print(blob_str(&val),4,79);
}else{
fossil_print("%s\n",blob_str(&val));
}
blob_reset(&val);
}
}
manifest_destroy(pTicket);
}
}
db_finalize(&q);
return;
}
/* read all given ticket field/value pairs from command line */
if( i==g.argc ){
fossil_fatal("empty %s command aborted!",g.argv[2]);
}
getAllTicketFields();
/* read commandline and assign fields in the azValue array */
while( i<g.argc ){
char *zFName;
char *zFValue;
int j;
int append = 0;
zFName = g.argv[i++];
if( i==g.argc ){
fossil_fatal("missing value for '%s'!",zFName);
}
zFValue = g.argv[i++];
if( tktEncoding == tktFossilize ){
zFValue=mprintf("%s",zFValue);
defossilize(zFValue);
}
append = (zFName[0] == '+');
if (append){
zFName++;
}
j = fieldId(zFName);
if( j == -1 ){
fossil_fatal("unknown field name '%s'!",zFName);
}else{
if (append) {
azAppend[j] = zFValue;
} else {
azValue[j] = zFValue;
}
}
}
/* now add the needed artifacts to the repository */
blob_zero(&tktchng);
/* add the time to the ticket manifest */
blob_appendf(&tktchng, "D %s\n", zDate);
/* append defined elements */
for(i=0; i<nField; i++){
char *zValue = 0;
char *zPfx;
if (azAppend[i] && azAppend[i][0] ){
zPfx = " +";
zValue = azAppend[i];
} else if( azValue[i] && azValue[i][0] ){
zPfx = " ";
zValue = azValue[i];
} else {
continue;
}
if( strncmp(azField[i], "private_", 8)==0 ){
zValue = db_conceal(zValue, strlen(zValue));
blob_appendf(&tktchng, "J%s%s %s\n", zPfx, azField[i], zValue);
}else{
blob_appendf(&tktchng, "J%s%s %#F\n", zPfx,
azField[i], strlen(zValue), zValue);
}
}
blob_appendf(&tktchng, "K %s\n", zTktUuid);
blob_appendf(&tktchng, "U %F\n", zUser);
md5sum_blob(&tktchng, &cksum);
blob_appendf(&tktchng, "Z %b\n", &cksum);
rid = content_put(&tktchng);
if( rid==0 ){
fossil_panic("trouble committing ticket: %s", g.zErrMsg);
}
manifest_crosslink_begin();
manifest_crosslink(rid, &tktchng);
manifest_crosslink_end();
assert( blob_is_reset(&tktchng) );
printf("ticket %s succeeded for %s\n",
(eCmd==set?"set":"add"),zTktUuid);
}
}
}
|
Changes to src/translate.c.
| ︙ | ︙ | |||
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 | ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** Input lines that begin with the "@" character are translated into ** either cgi_printf() statements or string literals and the ** translated code is written on standard output. ** ** The problem this program is attempt to solve is as follows: When ** writing CGI programs in C, we typically want to output a lot of HTML ** text to standard output. In pure C code, this involves doing a ** printf() with a big string containing all that text. But we have ** to insert special codes (ex: \n and \") for many common characters, ** which interferes with the readability of the HTML. ** ** This tool allows us to put raw HTML, without the special codes, in ** the middle of a C program. This program then translates the text ** into standard C by inserting all necessary backslashes and other ** punctuation. */ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h> /* | > > > | 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 | ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** SYNOPSIS: ** ** Input lines that begin with the "@" character are translated into ** either cgi_printf() statements or string literals and the ** translated code is written on standard output. ** ** The problem this program is attempt to solve is as follows: When ** writing CGI programs in C, we typically want to output a lot of HTML ** text to standard output. In pure C code, this involves doing a ** printf() with a big string containing all that text. But we have ** to insert special codes (ex: \n and \") for many common characters, ** which interferes with the readability of the HTML. ** ** This tool allows us to put raw HTML, without the special codes, in ** the middle of a C program. This program then translates the text ** into standard C by inserting all necessary backslashes and other ** punctuation. ** */ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h> /* |
| ︙ | ︙ | |||
117 118 119 120 121 122 123 |
fprintf(out,"\n");
}else{
fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
}
}else{
/* Otherwise (if the last non-whitespace was not '=') then generate
** a cgi_printf() statement whose format is the text following the '@'.
| | | | > > | | | < | | > | | | | 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 |
fprintf(out,"\n");
}else{
fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
}
}else{
/* Otherwise (if the last non-whitespace was not '=') then generate
** a cgi_printf() statement whose format is the text following the '@'.
** Substrings of the form "%C(...)" (where C is any sequence of
** characters other than \000 and '(') will put "%C" in the
** format and add the "(...)" as an argument to the cgi_printf call.
*/
int indent;
int nC;
char c;
i++;
if( isspace(zLine[i]) ){ i++; }
indent = i;
for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
zOut[j++] = zLine[i];
if( zLine[i]!='%' || zLine[i+1]=='%' || zLine[i+1]==0 ) continue;
for(nC=1; zLine[i+nC] && zLine[i+nC]!='('; nC++){}
if( zLine[i+nC]!='(' || !isalpha(zLine[i+nC-1]) ) continue;
while( --nC ) zOut[j++] = zLine[++i];
zArg[nArg++] = ',';
k = 0; i++;
while( (c = zLine[i])!=0 ){
zArg[nArg++] = c;
if( c==')' ){
k--;
if( k==0 ) break;
}else if( c=='(' ){
k++;
}
i++;
}
}
zOut[j] = 0;
if( !inPrint ){
fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
inPrint = 1;
}else{
|
| ︙ | ︙ |
Changes to src/user.c.
| ︙ | ︙ | |||
463 464 465 466 467 468 469 |
style_submenu_element("All", "All entries",
"%s/access_log?n=10000000", g.zTop);
}
@ </table></center>
db_finalize(&q);
@ <hr>
@ <form method="post" action="%s(g.zTop)/access_log">
| | | | | | | | | | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
style_submenu_element("All", "All entries",
"%s/access_log?n=10000000", g.zTop);
}
@ </table></center>
db_finalize(&q);
@ <hr>
@ <form method="post" action="%s(g.zTop)/access_log">
@ <label><input type="checkbox" name="delold">
@ Delete all but the most recent 200 entries</input></label>
@ <input type="submit" name="deloldbtn" value="Delete"></input>
@ </form>
@ <form method="post" action="%s(g.zTop)/access_log">
@ <label><input type="checkbox" name="delanon">
@ Delete all entries for user "anonymous"</input></label>
@ <input type="submit" name="delanonbtn" value="Delete"></input>
@ </form>
@ <form method="post" action="%s(g.zTop)/access_log">
@ <label><input type="checkbox" name="delfail">
@ Delete all failed login attempts</input></label>
@ <input type="submit" name="delfailbtn" value="Delete"></input>
@ </form>
@ <form method="post" action="%s(g.zTop)/access_log">
@ <label><input type="checkbox" name="delall">
@ Delete all entries</input></label>
@ <input type="submit" name="delallbtn" value="Delete"></input>
@ </form>
style_footer();
}
|
Changes to src/vfile.c.
| ︙ | ︙ | |||
204 205 206 207 208 209 210 |
db_ephemeral_blob(&q, 5, &origCksum);
if( sha1sum_file(zName, &fileCksum) ){
blob_zero(&fileCksum);
}
if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
blob_reset(&origCksum);
blob_reset(&fileCksum);
| > | | > | | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
db_ephemeral_blob(&q, 5, &origCksum);
if( sha1sum_file(zName, &fileCksum) ){
blob_zero(&fileCksum);
}
if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
blob_reset(&origCksum);
blob_reset(&fileCksum);
}else if( (chnged==0 || chnged==2)
&& (useMtime==0 || currentMtime!=oldMtime) ){
/* For files that were formerly believed to be unchanged or that were
** changed by merging, if their mtime changes, or unconditionally
** if --sha1sum is used, check to see if they have been edited by
** looking at their SHA1 sum */
assert( origSize==currentSize );
db_ephemeral_blob(&q, 5, &origCksum);
if( sha1sum_file(zName, &fileCksum) ){
blob_zero(&fileCksum);
}
if( blob_compare(&fileCksum, &origCksum) ){
chnged = 1;
|
| ︙ | ︙ | |||
469 470 471 472 473 474 475 |
void vfile_aggregate_checksum_disk(int vid, Blob *pOut){
FILE *in;
Stmt q;
char zBuf[4096];
db_must_be_within_tree();
db_prepare(&q,
| | | | | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
void vfile_aggregate_checksum_disk(int vid, Blob *pOut){
FILE *in;
Stmt q;
char zBuf[4096];
db_must_be_within_tree();
db_prepare(&q,
"SELECT %Q || pathname, pathname, origname, is_selected(id), rid"
" FROM vfile"
" WHERE (NOT deleted OR NOT is_selected(id)) AND vid=%d"
" ORDER BY if_selected(id, pathname, origname) /*scan*/",
g.zLocalRoot, vid
);
md5sum_init();
while( db_step(&q)==SQLITE_ROW ){
const char *zFullpath = db_column_text(&q, 0);
const char *zName = db_column_text(&q, 1);
int isSelected = db_column_int(&q, 3);
|
| ︙ | ︙ | |||
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 |
blob_reset(&file);
}
}
}
db_finalize(&q);
md5sum_finish(pOut);
}
/*
** Do a file-by-file comparison of the content of the repository and
** the working check-out on disk. Report any errors.
*/
void vfile_compare_repository_to_disk(int vid){
int rc;
Stmt q;
Blob disk, repo;
db_must_be_within_tree();
db_prepare(&q,
"SELECT %Q || pathname, pathname, rid FROM vfile"
| > > > > > > > > > > > > > > > > | > | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 |
blob_reset(&file);
}
}
}
db_finalize(&q);
md5sum_finish(pOut);
}
/*
** Write a BLOB into a random filename. Return the name of the file.
*/
static char *write_blob_to_temp_file(Blob *pBlob){
sqlite3_uint64 r;
char *zOut = 0;
do{
sqlite3_free(zOut);
sqlite3_randomness(8, &r);
zOut = sqlite3_mprintf("file-%08llx", r);
}while( file_size(zOut)>=0 );
blob_write_to_file(pBlob, zOut);
return zOut;
}
/*
** Do a file-by-file comparison of the content of the repository and
** the working check-out on disk. Report any errors.
*/
void vfile_compare_repository_to_disk(int vid){
int rc;
Stmt q;
Blob disk, repo;
char *zOut;
db_must_be_within_tree();
db_prepare(&q,
"SELECT %Q || pathname, pathname, rid FROM vfile"
" WHERE NOT deleted AND vid=%d AND is_selected(id)"
" ORDER BY if_selected(id, pathname, origname) /*scan*/",
g.zLocalRoot, vid
);
md5sum_init();
while( db_step(&q)==SQLITE_ROW ){
const char *zFullpath = db_column_text(&q, 0);
const char *zName = db_column_text(&q, 1);
int rid = db_column_int(&q, 2);
|
| ︙ | ︙ | |||
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
continue;
}
blob_zero(&repo);
content_get(rid, &repo);
if( blob_size(&repo)!=blob_size(&disk) ){
fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n",
zName, blob_size(&disk), blob_size(&repo));
blob_reset(&disk);
blob_reset(&repo);
continue;
}
if( blob_compare(&repo, &disk) ){
fossil_print(
"ERROR: [%s] is different on disk compared to the repository\n",
zName);
}
blob_reset(&disk);
blob_reset(&repo);
}
db_finalize(&q);
}
| > > > > > > > > | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 |
continue;
}
blob_zero(&repo);
content_get(rid, &repo);
if( blob_size(&repo)!=blob_size(&disk) ){
fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n",
zName, blob_size(&disk), blob_size(&repo));
zOut = write_blob_to_temp_file(&repo);
fossil_print("NOTICE: Repository version of [%s] stored in [%s]\n",
zName, zOut);
sqlite3_free(zOut);
blob_reset(&disk);
blob_reset(&repo);
continue;
}
if( blob_compare(&repo, &disk) ){
fossil_print(
"ERROR: [%s] is different on disk compared to the repository\n",
zName);
zOut = write_blob_to_temp_file(&repo);
fossil_print("NOTICE: Repository version of [%s] stored in [%s]\n",
zName, zOut);
sqlite3_free(zOut);
}
blob_reset(&disk);
blob_reset(&repo);
}
db_finalize(&q);
}
|
| ︙ | ︙ | |||
599 600 601 602 603 604 605 |
void vfile_aggregate_checksum_repository(int vid, Blob *pOut){
Blob file;
Stmt q;
char zBuf[100];
db_must_be_within_tree();
| | | | | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 |
void vfile_aggregate_checksum_repository(int vid, Blob *pOut){
Blob file;
Stmt q;
char zBuf[100];
db_must_be_within_tree();
db_prepare(&q, "SELECT pathname, origname, rid, is_selected(id)"
" FROM vfile"
" WHERE (NOT deleted OR NOT is_selected(id))"
" AND rid>0 AND vid=%d"
" ORDER BY if_selected(id,pathname,origname) /*scan*/",
vid);
blob_zero(&file);
md5sum_init();
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zOrigName = db_column_text(&q, 1);
int rid = db_column_int(&q, 2);
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
102 103 104 105 106 107 108 |
g.isHome = 1;
wiki_page();
return;
}
style_header("Home");
@ <p>This is a stub home-page for the project.
@ To fill in this page, first go to
| | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
g.isHome = 1;
wiki_page();
return;
}
style_header("Home");
@ <p>This is a stub home-page for the project.
@ To fill in this page, first go to
@ %z(href("%R/setup_config"))setup/config</a>
@ and establish a "Project Name". Then create a
@ wiki page with that name. The content of that wiki page
@ will be displayed in place of this message.</p>
style_footer();
}
/*
|
| ︙ | ︙ | |||
140 141 142 143 144 145 146 |
if( !g.perm.RdWiki ){ login_needed(); return; }
zPageName = P("name");
if( zPageName==0 ){
style_header("Wiki");
@ <ul>
{ char *zHomePageName = db_get("project-name",0);
if( zHomePageName ){
| | | < | < | | | | | 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 |
if( !g.perm.RdWiki ){ login_needed(); return; }
zPageName = P("name");
if( zPageName==0 ){
style_header("Wiki");
@ <ul>
{ char *zHomePageName = db_get("project-name",0);
if( zHomePageName ){
@ <li> %z(href("%R/wiki?name=%t",zHomePageName))
@ %h(zHomePageName)</a> wiki home page.</li>
}
}
@ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
@ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
@ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
@ to experiment.</li>
if( g.perm.NewWiki ){
@ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li>
if( g.perm.Write ){
@ <li> Create a %z(href("%R/eventedit"))new event</a>.</li>
}
}
@ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a>
@ available on this server.</li>
@ <li> <form method="get" action="%s(g.zTop)/wfind"><div>
@ Search wiki titles: <input type="text" name="title"/>
@ <input type="submit" /></div></form>
@ </li>
@ </ul>
style_footer();
|
| ︙ | ︙ | |||
190 191 192 193 194 195 196 |
if( !g.isHome ){
if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
g.zTop, zPageName);
}
if( rid && g.perm.ApndWiki && g.perm.Attach ){
style_submenu_element("Attach", "Add An Attachment",
| | | | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
if( !g.isHome ){
if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
g.zTop, zPageName);
}
if( rid && g.perm.ApndWiki && g.perm.Attach ){
style_submenu_element("Attach", "Add An Attachment",
"%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
g.zTop, zPageName, g.zTop, zPageName);
}
if( rid && g.perm.ApndWiki ){
style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T",
g.zTop, zPageName);
}
if( g.perm.Hyperlink ){
style_submenu_element("History", "History", "%s/whistory?name=%T",
g.zTop, zPageName);
}
}
style_header(zPageName);
blob_init(&wiki, zBody, -1);
wiki_convert(&wiki, 0, 0);
|
| ︙ | ︙ | |||
223 224 225 226 227 228 229 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
| | | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
if( g.perm.Hyperlink && g.perm.Read ){
@ %z(href("%R/attachview?page=%T&file=%t",zPageName,zFile))
@ %h(zFile)</a>
}else{
@ %h(zFile)
}
@ added by %h(zUser) on
hyperlink_to_date(zDate, ".");
if( g.perm.WrWiki && g.perm.Attach ){
@ [%z(href("%R/attachdelete?page=%t&file=%t&from=%R/wiki%%3fname=%f",zPageName,zFile,zPageName))delete</a>]
}
@ </li>
}
if( cnt ){
@ </ul>
}
db_finalize(&q);
|
| ︙ | ︙ | |||
542 543 544 545 546 547 548 |
/*
** Function called to output extra text at the end of each line in
** a wiki history listing.
*/
static void wiki_history_extra(int rid){
if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){
| | | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 |
/*
** Function called to output extra text at the end of each line in
** a wiki history listing.
*/
static void wiki_history_extra(int rid){
if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){
@ %z(href("%R/wdiff?name=%t&a=%d",zWikiPageName,rid))[diff]</a>
}
}
/*
** WEBPAGE: whistory
** URL: /whistory?name=PAGENAME
**
** Show the complete change history for a single wiki page.
*/
void whistory_page(void){
Stmt q;
char *zTitle;
char *zSQL;
const char *zPageName;
login_check_credentials();
if( !g.perm.Hyperlink ){ login_needed(); return; }
zPageName = PD("name","");
zTitle = mprintf("History Of %s", zPageName);
style_header(zTitle);
free(zTitle);
zSQL = mprintf("%s AND event.objid IN "
" (SELECT rid FROM tagxref WHERE tagid="
|
| ︙ | ︙ | |||
595 596 597 598 599 600 601 |
const char *zPageName;
Manifest *pW1, *pW2 = 0;
Blob w1, w2, d;
int diffFlags;
login_check_credentials();
rid1 = atoi(PD("a","0"));
| | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 |
const char *zPageName;
Manifest *pW1, *pW2 = 0;
Blob w1, w2, d;
int diffFlags;
login_check_credentials();
rid1 = atoi(PD("a","0"));
if( !g.perm.Hyperlink ){ login_needed(); return; }
if( rid1==0 ) fossil_redirect_home();
rid2 = atoi(PD("b","0"));
zPageName = PD("name","");
zTitle = mprintf("Changes To %s", zPageName);
style_header(zTitle);
free(zTitle);
|
| ︙ | ︙ | |||
672 673 674 675 676 677 678 |
}
@ <ul>
wiki_prepare_page_list(&q);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
int size = db_column_int(&q, 1);
if( size>0 ){
| | | | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 |
}
@ <ul>
wiki_prepare_page_list(&q);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
int size = db_column_int(&q, 1);
if( size>0 ){
@ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li>
}else if( showAll ){
@ <li>%z(href("%R/wiki?name=%T",zName))<s>%h(zName)</s></a></li>
}
}
db_finalize(&q);
@ </ul>
style_footer();
}
|
| ︙ | ︙ | |||
702 703 704 705 706 707 708 |
@ <ul>
db_prepare(&q,
"SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
" ORDER BY lower(tagname) /*sort*/" ,
zTitle);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
| | | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 |
@ <ul>
db_prepare(&q,
"SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
" ORDER BY lower(tagname) /*sort*/" ,
zTitle);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
@ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li>
}
db_finalize(&q);
@ </ul>
style_footer();
}
/*
|
| ︙ | ︙ |
Changes to src/wikiformat.c.
| ︙ | ︙ | |||
1041 1042 1043 1044 1045 1046 1047 |
|| strncmp(zTarget, "https:", 6)==0
|| strncmp(zTarget, "ftp:", 4)==0
|| strncmp(zTarget, "mailto:", 7)==0
){
blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
/* zTerm = "⟾</a>"; // doesn't work on windows */
}else if( zTarget[0]=='/' ){
| < | < < < | | | | | | < < | | | 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 |
|| strncmp(zTarget, "https:", 6)==0
|| strncmp(zTarget, "ftp:", 4)==0
|| strncmp(zTarget, "mailto:", 7)==0
){
blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
/* zTerm = "⟾</a>"; // doesn't work on windows */
}else if( zTarget[0]=='/' ){
blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget);
}else if( zTarget[0]=='.' || zTarget[0]=='#' ){
if( 1 ){
blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
}else{
zTerm = "";
}
}else if( is_valid_uuid(zTarget) ){
int isClosed = 0;
if( is_ticket(zTarget, &isClosed) ){
/* Special display processing for tickets. Display the hyperlink
** as crossed out if the ticket is closed.
*/
if( isClosed ){
if( g.perm.Hyperlink ){
blob_appendf(p->pOut,
"%z<span class=\"wikiTagCancelled\">[",
href("%R/info/%s",zTarget)
);
zTerm = "]</span></a>";
}else{
blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">[");
zTerm = "]</span>";
}
}else{
if( g.perm.Hyperlink ){
blob_appendf(p->pOut,"%z[", href("%R/info/%s", zTarget));
zTerm = "]</a>";
}else{
blob_appendf(p->pOut, "[");
zTerm = "]";
}
}
}else if( !in_this_repo(zTarget) ){
blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget);
zTerm = "]</span>";
}else if( g.perm.Hyperlink ){
blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
zTerm = "]</a>";
}
}else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
&& db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
blob_appendf(p->pOut, "<a href=\"%s/timeline?c=%T\">", g.zTop, zTarget);
}else if( strncmp(zTarget, "wiki:", 5)==0
&& wiki_name_is_wellformed((const unsigned char*)zTarget) ){
|
| ︙ | ︙ |
Changes to src/winhttp.c.
| ︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
/*
** Get message string of the last system error. Return a pointer to the
** message string. Call fossil_mbcs_free() to deallocate any memory used
** to store the message string when done.
*/
static char *win32_get_last_errmsg(void){
DWORD nMsg;
LPTSTR tmp = NULL;
char *zMsg = NULL;
nMsg = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
| > > | > > > > > > > > > > > > > > | | 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 |
/*
** Get message string of the last system error. Return a pointer to the
** message string. Call fossil_mbcs_free() to deallocate any memory used
** to store the message string when done.
*/
static char *win32_get_last_errmsg(void){
DWORD nMsg;
DWORD nErr = GetLastError();
LPTSTR tmp = NULL;
char *zMsg = NULL;
/* Try first to get the error text in english. */
nMsg = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
nErr,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPTSTR) &tmp,
0,
NULL
);
if( !nMsg ){
/* No english, get what the system has available. */
nMsg = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
nErr,
0,
(LPTSTR) &tmp,
0,
NULL
);
}
if( nMsg ){
zMsg = fossil_mbcs_to_utf8(tmp);
}else{
fossil_fatal("unable to get system error message.");
}
if( tmp ){
LocalFree((HLOCAL) tmp);
}
return zMsg;
}
/*
** Report the current status of the service to the service control manager.
** Make sure that during service startup no control codes are accepted.
*/
static void win32_report_service_status(
DWORD dwCurrentState, /* The current state of the service */
DWORD dwWin32ExitCode, /* The error code to report */
DWORD dwWaitHint /* The estimated time for a pending operation */
){
if( dwCurrentState==SERVICE_START_PENDING ){
ssStatus.dwControlsAccepted = 0;
}else{
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
}
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
|
| ︙ | ︙ | |||
475 476 477 478 479 480 481 | ** -W|--password PASSWORD ** ** Password for the user account. ** ** The following options are more or less the same as for the "server" ** command and influence the behaviour of the http server: ** | | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | ** -W|--password PASSWORD ** ** Password for the user account. ** ** The following options are more or less the same as for the "server" ** command and influence the behaviour of the http server: ** ** -P|--port TCPPORT ** ** Specifies the TCP port (default port is 8080) on which the ** server should listen. ** ** -R|--repository REPOSITORY ** ** Specifies the name of the repository to be served. |
| ︙ | ︙ | |||
542 543 544 545 546 547 548 |
const char *zSvcName = "Fossil-DSCM"; /* Default service name */
if( g.argc<3 ){
usage("create|delete|show|start|stop ...");
}
zMethod = g.argv[2];
n = strlen(zMethod);
| < < < | | | | | | | | > > > > > > < < | < < < < < < < < | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 |
const char *zSvcName = "Fossil-DSCM"; /* Default service name */
if( g.argc<3 ){
usage("create|delete|show|start|stop ...");
}
zMethod = g.argv[2];
n = strlen(zMethod);
if( strncmp(zMethod, "create", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_DESCRIPTION
svcDescr = {"Fossil - Distributed Software Configuration Management"};
char *zErrFmt = "unable to create service '%s': %s";
DWORD dwStartType = SERVICE_DEMAND_START;
const char *zDisplay = find_option("display", "D", 1);
const char *zStart = find_option("start", "S", 1);
const char *zUsername = find_option("username", "U", 1);
const char *zPassword = find_option("password", "W", 1);
const char *zPort = find_option("port", "P", 1);
const char *zNotFound = find_option("notfound", 0, 1);
const char *zLocalAuth = find_option("localauth", 0, 0);
const char *zRepository = find_option("repository", "R", 1);
Blob binPath;
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for create method.");
}
/* Process service creation specific options. */
if( !zDisplay ){
zDisplay = zSvcName;
}
if( zStart ){
if( strncmp(zStart, "auto", strlen(zStart))==0 ){
dwStartType = SERVICE_AUTO_START;
}else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
dwStartType = SERVICE_DEMAND_START;
}else{
fossil_fatal(zErrFmt, zSvcName,
"specify 'auto' or 'manual' for the '-S|--start' option");
}
}
/* Process options for Fossil running as server. */
if( zPort && (atoi(zPort)<=0) ){
fossil_fatal(zErrFmt, zSvcName,
"port number must be in the range 1 - 65535.");
}
if( !zRepository ){
db_must_be_within_tree();
}else if( file_isdir(zRepository)==1 ){
g.zRepositoryName = mprintf("%s", zRepository);
file_simplify_name(g.zRepositoryName, -1, 0);
}else{
db_open_repository(zRepository);
}
db_close(0);
/* Build the fully-qualified path to the service binary file. */
blob_zero(&binPath);
blob_appendf(&binPath, "\"%s\" server", fossil_nameofexe());
if( zPort ) blob_appendf(&binPath, " --port %s", zPort);
if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound);
if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
|
| ︙ | ︙ | |||
640 641 642 643 644 645 646 |
if( strncmp(zMethod, "delete", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to delete service '%s': %s";
verify_all_options();
| > > > | > | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
if( strncmp(zMethod, "delete", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to delete service '%s': %s";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for delete method.");
}
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
QueryServiceStatus(hSvc, &sstat);
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
fossil_print("Stopping service '%s'", zSvcName);
|
| ︙ | ︙ | |||
704 705 706 707 708 709 710 |
static const char *zSvcStates[] = {
"Stopped", "Starting", "Stopping", "Running",
"Continue pending", "Pause pending", "Paused"
};
const char *zSvcState = "";
verify_all_options();
| > > > | > | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 |
static const char *zSvcStates[] = {
"Stopped", "Starting", "Stopping", "Running",
"Continue pending", "Pause pending", "Paused"
};
const char *zSvcState = "";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for show method.");
}
hScm = OpenSCManager(NULL, NULL, GENERIC_READ);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), GENERIC_READ);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
/* Get the service configuration */
bStatus = QueryServiceConfig(hSvc, NULL, 0, &nRequired);
if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
|
| ︙ | ︙ | |||
782 783 784 785 786 787 788 |
if( strncmp(zMethod, "start", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to start service '%s': %s";
verify_all_options();
| > > > | > | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 |
if( strncmp(zMethod, "start", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to start service '%s': %s";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for start method.");
}
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
QueryServiceStatus(hSvc, &sstat);
if( sstat.dwCurrentState!=SERVICE_RUNNING ){
fossil_print("Starting service '%s'", zSvcName);
|
| ︙ | ︙ | |||
814 815 816 817 818 819 820 |
if( strncmp(zMethod, "stop", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to stop service '%s': %s";
verify_all_options();
| > > > | > | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 |
if( strncmp(zMethod, "stop", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to stop service '%s': %s";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for stop method.");
}
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
QueryServiceStatus(hSvc, &sstat);
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
fossil_print("Stopping service '%s'", zSvcName);
|
| ︙ | ︙ |
Changes to src/zip.c.
| ︙ | ︙ | |||
427 428 429 430 431 432 433 |
int nName, nRid;
Blob zip;
login_check_credentials();
if( !g.perm.Zip ){ login_needed(); return; }
zName = mprintf("%s", PD("name",""));
nName = strlen(zName);
| | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
int nName, nRid;
Blob zip;
login_check_credentials();
if( !g.perm.Zip ){ login_needed(); return; }
zName = mprintf("%s", PD("name",""));
nName = strlen(zName);
zRid = mprintf("%s", PD("uuid","trunk"));
nRid = strlen(zRid);
for(nName=strlen(zName)-1; nName>5; nName--){
if( zName[nName]=='.' ){
zName[nName] = 0;
break;
}
}
|
| ︙ | ︙ |
Changes to test/diff-test-1.wiki.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 |
Multiple edits on a single line.</a> This is an SQLite version
update diff. It is a large diff and contains many other interesting
features. Scan the whole diff.
* <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
target="testwindow">Tricky alignment and multiple edits per line</a>.
* <a href="../../../fdiff?v1=7108d4748b111d23&v2=2303a98525b39d19#chunk3"
target="testwindow">Add a column to a table</a>
External:
* <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
Code indentation change.</a>
| > > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
Multiple edits on a single line.</a> This is an SQLite version
update diff. It is a large diff and contains many other interesting
features. Scan the whole diff.
* <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
target="testwindow">Tricky alignment and multiple edits per line</a>.
* <a href="../../../fdiff?v1=7108d4748b111d23&v2=2303a98525b39d19#chunk3"
target="testwindow">Add a column to a table</a>
* <a href="../../../fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"
target="testwindow">Column alignment with multibyte characters.</a>
The edit of a line with multibyte characters is the first chunk.
* <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
target="testwindow">Large diff of sqlite3.c</a>. This diff was very
slow prior to the preformance enhancement change [9e15437e97].
External:
* <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
Code indentation change.</a>
|
Changes to test/graph-test-1.wiki.
| ︙ | ︙ | |||
27 28 29 30 31 32 33 |
* <a href="../../../timeline?y=ci&a=2010-12-20" target="testwindow">
multiple branch risers.</a>
* <a href="../../../timeline?y=ci&a=2010-12-20&n=18" target="testwindow">
multiple branch risers, n=18.</a>
* <a href="../../../timeline?y=ci&a=2010-12-20&n=9" target="testwindow">
multiple branch risers, n=9.</a>
* <a href="../../../timeline?r=experimental" target="testwindow">
| | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
* <a href="../../../timeline?y=ci&a=2010-12-20" target="testwindow">
multiple branch risers.</a>
* <a href="../../../timeline?y=ci&a=2010-12-20&n=18" target="testwindow">
multiple branch risers, n=18.</a>
* <a href="../../../timeline?y=ci&a=2010-12-20&n=9" target="testwindow">
multiple branch risers, n=9.</a>
* <a href="../../../timeline?r=experimental" target="testwindow">
Experimental branch with related check-ins.</a>
* <a href="../../../timeline?r=experimental&mionly" target="testwindow">
Experimental branch with merge-ins only.</a>
* <a href="../../../timeline?t=experimental" target="testwindow">
Experimental branch check-ins only.</a>
* <a href="../../../timeline?r=experimental&n=1000" target="testwindow">
Experimental branch using and related check-ins - 1000 elements.</a>
* <a href="../../../timeline?r=release" target="testwindow">
Check-ins tagged "release" and related check-ins</a>
* <a href="../../../timeline?r=release&mionly" target="testwindow">
|
| ︙ | ︙ |
Added tools/fossilwiki.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
#!/usr/bin/perl
# vim: cin :
$repofile = shift;
$repocmd = '';
$repocmd = "-R $repofile" if -f $repofile;
$mainpage = '';
@rep = ();
if ( ! -f $repofile )
{
@rep = `fossil info | grep 'project-name'`;
}
else
{
@rep = `fossil info $repofile | grep 'project-name'`;
}
$mainpage = $rep[0];
chomp $mainpage;
$mainpage =~ s/^project-name:\s+//;
@pages = `fossil wiki list $repocmd`;
%pages = ();
foreach $page ( @pages )
{
chomp $page;
$text = `fossil wiki export "$page" $repocmd`;
$pages{$page} = $text;
}
@orphans = ();
@nointernals = ();
@terminals = ();
@empties = ();
%badlinks = ();
%alllinks = ();
%links = ();
foreach $page ( keys %pages )
{
my @links = ();
my $text = $pages{$page};
while ( $text =~ m/\[([^][]+)\]/g )
{
push @links,$1;
}
$numlinks = $#links;
if (@links == ())
{
push @terminals, $page;
}
else
{
my @internals = grep { $_ !~ /(http:)|(mailto:)|(https:)/ } @links;
if (@internals == ())
{
push @nointernals, $page;
}
else
{
@{$links{$page}{'links'}} = map {my ($a,$b) = split /\|/; $a;} @internals;
foreach $internal ( @internals )
{
my ($int_link, $display) = split /\|/, $internal;
${$links{$int_link}{'refs'}}++;
$alllinks{$int_link} = 1;
}
}
}
if ($text eq '' || $text =~ m/^<i>Empty Page<\/i>/)
{
chomp $tail;
my ($head, $tail) = split /\/i>/ , $text;
if ($tail =~ m/^\s*$/s) {
push @empties, $page;
}
}
}
foreach $page ( keys %links )
{
if ($page ne $mainpage && (${$links{$page}{'refs'}} == 0))
{
push @orphans, $page;
}
}
foreach $link (keys %alllinks )
{
if (! exists($pages{$link}) && $link !~ /^\./ && $link !~ /^\//)
{
$badlinks{$link} = 1;
}
}
foreach $empty ( @empties )
{
print ("empty: '$empty'\n");
}
foreach $nointernals ( @nointernals )
{
print ("nointernals: '$nointernals'\n");
}
foreach $terminal ( @terminals )
{
print ("terminal: '$terminal'\n");
}
foreach $orphan ( @orphans )
{
print ("orphan: '$orphan'\n");
}
foreach $link ( keys %badlinks )
{
print ("badlink: '$link'\n");
}
foreach $page ( sort keys %links )
{
my @links = @{$links{$page}{'links'}};
if (@links != ())
{
if ($page eq $mainpage)
{
print "links: *** '$page' *** -> ", join (", ", @links), "\n";
}
else
{
print "links: '$page' -> ", join (", ", @links), "\n";
}
}
}
|
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # ZINCDIR = $(SRCDIR)/../zlib-1.2.7 ZLIBDIR = $(SRCDIR)/../zlib-1.2.7 #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLINCDIR = $(SRCDIR)/../openssl-1.0.1c/include OPENSSLLIBDIR = $(SRCDIR)/../openssl-1.0.1c #### Either the directory where the Tcl library is installed or the Tcl # source code directory resides (depending on the value of the macro # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, # this directory must have "include" and "lib" sub-directories. If # this points to the Tcl source code directory, this directory must # have "generic" and "win" sub-directories. The recommended usage |
| ︙ | ︙ | |||
95 96 97 98 99 100 101 | # the finished binary for fossil. The BCC compiler above is used # for building intermediate code-generator tools. # TCC = gcc -Os -Wall -L$(ZLIBDIR) -I$(ZINCDIR) # With HTTPS support ifdef FOSSIL_ENABLE_SSL | < | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | # the finished binary for fossil. The BCC compiler above is used # for building intermediate code-generator tools. # TCC = gcc -Os -Wall -L$(ZLIBDIR) -I$(ZINCDIR) # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -L$(OPENSSLLIBDIR) -I$(OPENSSLINCDIR) endif # With Tcl support ifdef FOSSIL_ENABLE_TCL ifdef FOSSIL_TCL_SOURCE TCC += -L$(TCLSRCDIR)/win -I$(TCLSRCDIR)/generic -I$(TCLSRCDIR)/win |
| ︙ | ︙ | |||
467 468 469 470 471 472 473 | $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o APPNAME = fossil.exe | | | | | > | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o APPNAME = fossil.exe TRANSLATE = $(OBJDIR)/translate.exe MAKEHEADERS = $(OBJDIR)/makeheaders.exe MKINDEX = $(OBJDIR)/mkindex.exe VERSION = $(OBJDIR)/version.exe all: $(OBJDIR) $(APPNAME) $(OBJDIR)/icon.o: $(SRCDIR)/../win/icon.rc cp $(SRCDIR)/../win/icon.rc $(OBJDIR) windres $(OBJDIR)/icon.rc -o $(OBJDIR)/icon.o install: $(APPNAME) mkdir -p $(INSTALLDIR) mv $(APPNAME) $(INSTALLDIR) $(OBJDIR): mkdir $(OBJDIR) $(OBJDIR)/translate: $(SRCDIR)/translate.c $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| ︙ | ︙ | |||
1231 1232 1233 1234 1235 1236 1237 | $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o $(OBJDIR)/th.o: $(SRCDIR)/th.c | | | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o $(OBJDIR)/th.o: $(SRCDIR)/th.c $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o ifdef FOSSIL_ENABLE_TCL $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o endif |
Changes to win/Makefile.mingw.mistachkin.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # ZINCDIR = $(SRCDIR)/../zlib-1.2.7 ZLIBDIR = $(SRCDIR)/../zlib-1.2.7 #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLINCDIR = $(SRCDIR)/../openssl-1.0.1c/include OPENSSLLIBDIR = $(SRCDIR)/../openssl-1.0.1c #### Either the directory where the Tcl library is installed or the Tcl # source code directory resides (depending on the value of the macro # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, # this directory must have "include" and "lib" sub-directories. If # this points to the Tcl source code directory, this directory must # have "generic" and "win" sub-directories. The recommended usage |
| ︙ | ︙ | |||
95 96 97 98 99 100 101 | # the finished binary for fossil. The BCC compiler above is used # for building intermediate code-generator tools. # TCC = gcc -Os -Wall -L$(ZLIBDIR) -I$(ZINCDIR) # With HTTPS support ifdef FOSSIL_ENABLE_SSL | < | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | # the finished binary for fossil. The BCC compiler above is used # for building intermediate code-generator tools. # TCC = gcc -Os -Wall -L$(ZLIBDIR) -I$(ZINCDIR) # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -L$(OPENSSLLIBDIR) -I$(OPENSSLINCDIR) endif # With Tcl support ifdef FOSSIL_ENABLE_TCL ifdef FOSSIL_TCL_SOURCE TCC += -L$(TCLSRCDIR)/win -I$(TCLSRCDIR)/generic -I$(TCLSRCDIR)/win |
| ︙ | ︙ | |||
467 468 469 470 471 472 473 | $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o APPNAME = fossil.exe | | | | | | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o APPNAME = fossil.exe TRANSLATE = $(OBJDIR)/translate.exe MAKEHEADERS = $(OBJDIR)/makeheaders.exe MKINDEX = $(OBJDIR)/mkindex.exe VERSION = $(OBJDIR)/version.exe all: $(OBJDIR) $(APPNAME) $(OBJDIR)/icon.o: $(SRCDIR)/../win/icon.rc cp $(SRCDIR)/../win/icon.rc $(OBJDIR) windres $(OBJDIR)/icon.rc -o $(OBJDIR)/icon.o |
| ︙ | ︙ | |||
1231 1232 1233 1234 1235 1236 1237 | $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o $(OBJDIR)/th.o: $(SRCDIR)/th.c | | | | | 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 | $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o $(OBJDIR)/th.o: $(SRCDIR)/th.c $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o ifdef FOSSIL_ENABLE_TCL $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o endif |
Changes to www/changes.wiki.
1 2 3 4 5 6 7 8 9 |
<title>Change Log</title>
<h2>Changes For Version 1.22 (2012-03-17)</h2>
* Greatly improved "diff" processing including the new --brief option,
partial line matching, colorized in-line diffs, and better performance.
* Promote "allow-symlinks" to a versionable setting
* Harden the CGI processing logic against DOS attacks
* Add the ability to run TH1 scripts after sync requests
* Store the repository name in _FOSSIL_ as it is type in the "open" command,
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
<title>Change Log</title>
<h2>Changes For Version 1.23 (2012-08-08)</h2>
* The default checkout database name is now ".fslckout" instead of
"_FOSSIL_" on unix. Both names continue to work.
* Added the "fossil all changes" command
* Added the --ckout option to the "fossil all list" command
* Added the "public-pages" glob pattern that can be configured to allow
anonymous users to see embedded documentation on sites where source
code should not be accessible to anonymous users.
* Allow multiple --tag options on the same "fossil commit" command.
* Change the meaning of the --bgcolor option for "fossil commit" to only
change the color for that one commit. The new --branchcolor option
is available to set a persistent background color.
* Add the branch= query parameter to the vdiff page and the --branch option
to the "fossil diff" command.
* Check-in names of the form "root:BRANCH" now refer to the origin of
the branch. Hence to see all changes in a branch, use
"fossil diff --from root:BRANCH --to BRANCH". The --branch option on
the diff command is an alias for the same.
* Add the ability to configure ad-units to be displayed between the menu
bar and the content.
* Add the ability to set a background image as part of server configuration.
* Allow partial commits of cherrypick merges.
* Updates against an uncommitted merge are now a warning, not a fatal error.
* Prompt the user to continue if a check-in comment is unedited.
* Fixes to case sensitivity settings with the /dir webpage.
* Repositories now try to remember the locations of all checkouts and
web-access URLs and display this information with the
"fossil info $REPO" command.
* Improved defense against spiders: The src= attribute of
<a> elements is set using javascript after the page loads.
* Enhanced formatting of the user list page.
* If a file named in "fossil add" is missing, that is now a warning instead
of a fatal error.
* Fix side-by-side diff so that it displays correctly with
multi-byte UTF8 characters.
* Performance improvements in the diff logic.
* Other performance tweaks and documentation updates.
<h2>Changes For Version 1.22 (2012-03-17)</h2>
* Greatly improved "diff" processing including the new --brief option,
partial line matching, colorized in-line diffs, and better performance.
* Promote "allow-symlinks" to a versionable setting
* Harden the CGI processing logic against DOS attacks
* Add the ability to run TH1 scripts after sync requests
* Store the repository name in _FOSSIL_ as it is type in the "open" command,
|
| ︙ | ︙ |
Changes to www/checkin_names.wiki.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <title>Check-in Names</title> <table align="right" border="1" width="33%" cellpadding="10"> <tr><td> <h3>Executive Summary</h3> <p>A check-in can be identified using any of the following names: <ul> <li> SHA1 hash prefix <li> Tag or branchname <li> Timestamp: <i>YYYY-MM-DD HH:MM:SS</i> <li> <i>tag-name</i> <big><b>:</b></big> <i>timestamp</i> <li> Special names: <ul> <li> <b>tip</b> <li> <b>current</b> <li> <b>next</b> <li> <b>previous</b> <li> <b>ckout</b> | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <title>Check-in Names</title> <table align="right" border="1" width="33%" cellpadding="10"> <tr><td> <h3>Executive Summary</h3> <p>A check-in can be identified using any of the following names: <ul> <li> SHA1 hash prefix <li> Tag or branchname <li> Timestamp: <i>YYYY-MM-DD HH:MM:SS</i> <li> <i>tag-name</i> <big><b>:</b></big> <i>timestamp</i> <li> <b>root :</b> <i>branchname</i> <li> Special names: <ul> <li> <b>tip</b> <li> <b>current</b> <li> <b>next</b> <li> <b>previous</b> <li> <b>ckout</b> |
| ︙ | ︙ | |||
121 122 123 124 125 126 127 128 129 130 | A timestamp in one of the formats shown below means the most recent check-in that occurs no later than the timestamp given: * <i>YYYY-MM-DD</i> * <i>YYYY-MM-DD HH:MM</i> * <i>YYYY-MM-DD HH:MM:SS</i> The space between the day and the year can optionally be replaced by an uppercase <b>T</b> and the entire timestamp can | > | > > > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | A timestamp in one of the formats shown below means the most recent check-in that occurs no later than the timestamp given: * <i>YYYY-MM-DD</i> * <i>YYYY-MM-DD HH:MM</i> * <i>YYYY-MM-DD HH:MM:SS</i> * <i>YYYY-MM-DD HH:MM:SS.SSS</i> The space between the day and the year can optionally be replaced by an uppercase <b>T</b> and the entire timestamp can optionally be followed by "<b>z</b>" or "<b>Z</b>". In the fourth form with fractional seconds, any number of digits may follow the decimal point, though due to precision limits only the first three digits will be significant. In its default configuration, Fossil interprets and displays all dates in Universal Coordinated Time (UTC). This tends to work the best for distributed projects where participants are scattered around the globe. But there is an option on the Admin/Timeline page of the web-interface to switch to local time. The "<b>Z</b>" suffix on an timestamp check-in name is meaningless if Fossil is in the default mode of using UTC for |
| ︙ | ︙ | |||
165 166 167 168 169 170 171 172 173 174 175 176 177 178 | <blockquote> fossil update trunk:2010-07-01T14:30 </blockquote> Would cause Fossil to update the working check-out to be the most recent check-in on the trunk that is not more recent that 14:30 (UTC) on July 1, 2010. <h2>Special Tags</h2> The tag "tip" means the most recent check-in. The "tip" tag is roughly equivalent to the timestamp tag "5000-01-01". If the command is being run from a working check-out (not against a bare | > > > > > > > > > > > > > | 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 | <blockquote> fossil update trunk:2010-07-01T14:30 </blockquote> Would cause Fossil to update the working check-out to be the most recent check-in on the trunk that is not more recent that 14:30 (UTC) on July 1, 2010. <h2>Root Of A Branch</h2> A branch name that begins with the "<tt>root:</tt>" prefix refers to the last check-in in the parent branch prior to the beginning of the branch. Such a label is useful, for example, in computing all diffs for a single branch. The following example will show all changes in the hypothetical branch "xyzzy": <blockquote> fossil diff --from root:xyzzy --to xyzzy </blockquote> <h2>Special Tags</h2> The tag "tip" means the most recent check-in. The "tip" tag is roughly equivalent to the timestamp tag "5000-01-01". If the command is being run from a working check-out (not against a bare |
| ︙ | ︙ |
Changes to www/fileformat.wiki.
| ︙ | ︙ | |||
275 276 277 278 279 280 281 | <a name="ctrl"></a> <h2>3.0 Control Artifacts</h2> Control artifacts are used to assign properties to other artifacts within the repository. The basic format of a control artifact is the same as a manifest or cluster. A control artifact is a text | | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | <a name="ctrl"></a> <h2>3.0 Control Artifacts</h2> Control artifacts are used to assign properties to other artifacts within the repository. The basic format of a control artifact is the same as a manifest or cluster. A control artifact is a text file divided into cards by newline characters. Each card has a single-character card type followed by arguments. Spaces separate the card type and the arguments. No surplus whitespace is allowed. All cards must occur in strict lexicographical order. Allowed cards in a control artifact are as follows: <blockquote> |
| ︙ | ︙ |
Changes to www/quotes.wiki.
| ︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 | <li>We've been using git and github for a few months now, and it's not intuitive... I'm hoping someone will make a set of standard wrappers/GUI for making git bearable. <blockquote> <i>maro at [http://news.ycombinator.com/item?id=1433387]</i> </blockquote> </ol> <h2>On The Usability Of Fossil:</h2> <ol> | > > > > > > > | | 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 | <li>We've been using git and github for a few months now, and it's not intuitive... I'm hoping someone will make a set of standard wrappers/GUI for making git bearable. <blockquote> <i>maro at [http://news.ycombinator.com/item?id=1433387]</i> </blockquote> <li>Klingon Code Warriors embrace Git; we enjoy arbitrary conflicts. Git is not for the weak and feeble. TODAY IS A GOOD DAY TO CODE. <blockquote> <i>teastain at [http://www.reddit.com/r/programming/comments/xpitj/10_things_i_hate_about_git/c5oj4fk] </blockquote> </ol> <h2>On The Usability Of Fossil:</h2> <ol> <li value=6> Fossil mesmerizes me with simplicity especially after I struggled to get a bug-tracking system to work with mercurial. <blockquote> <i>rawjeev at [http://stackoverflow.com/questions/156322/what-do-people-think-of-the-fossil-dvcs]</i> </blockquote> |
| ︙ | ︙ | |||
65 66 67 68 69 70 71 | </ol> <h2>On Git Versus Fossil</h2> <ol> | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | </ol> <h2>On Git Versus Fossil</h2> <ol> <li value=8> Just want to say thanks for fossil making my life easier.... Also <nowiki>[for]</nowiki> not having a misanthropic command line interface. <blockquote> <i>Joshua Paine at [http://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg02736.html]</i> </blockquote> |
| ︙ | ︙ |
Changes to www/tech_overview.wiki.
| ︙ | ︙ | |||
289 290 291 292 293 294 295 | to have multiple working checkouts. Each working checkout has a single database in its root directory that records the state of that checkout. The checkout database is named "_FOSSIL_" by default, but can be renamed to ".fslckout" if desired. (Future versions of Fossil might make ".fslckout" the default name.) The checkout database records information such as the following: | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
to have multiple working checkouts. Each working checkout has a single
database in its root directory that records the state of that checkout.
The checkout database is named "_FOSSIL_" by default, but can be renamed
to ".fslckout" if desired. (Future versions of Fossil might make
".fslckout" the default name.) The checkout database records information
such as the following:
* The name of the repository database file.
* The version that is currently checked out.
* Files that have been [/help/add | added],
[/help/rm | removed], or [/help/mv | renamed] but not
yet committed.
* The mtime and size of files as they were originally checked out,
in order to expedite checking which files have been edited.
* Other checkins that have been [/help/merge | merged] into the
|
| ︙ | ︙ |