Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | merge trunk. Upgrade to openssl 1.1.0g |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | openssl-1.1 |
Files: | files | file ages | folders |
SHA3-256: | 9d3560b885c2a091e3ff624e0c78f0ff |
User & Date: | jan.nijtmans 2017-11-10 10:55:48 |
2018-03-28
| ||
08:06 | Merge trunk check-in: d9573d87 user: jan.nijtmans tags: openssl-1.1 | |
2017-11-10
| ||
10:55 | merge trunk. Upgrade to openssl 1.1.0g check-in: 9d3560b8 user: jan.nijtmans tags: openssl-1.1 | |
10:28 | Upgrade to openssl 1.0.2m check-in: 5310f2ba user: jan.nijtmans tags: trunk | |
2017-07-13
| ||
10:24 | merge trunk check-in: 548fabe7 user: jan.nijtmans tags: openssl-1.1 | |
Changes to Makefile.in.
47 48 49 50 51 52 53 |
USE_SEE = @USE_SEE@ FOSSIL_ENABLE_MINIZ = @FOSSIL_ENABLE_MINIZ@ include $(SRCDIR)/main.mk distclean: clean rm -f autoconfig.h config.log Makefile |
> > > > > > > > > > > > > > > > > > > > > |
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 |
USE_SEE = @USE_SEE@ FOSSIL_ENABLE_MINIZ = @FOSSIL_ENABLE_MINIZ@ include $(SRCDIR)/main.mk distclean: clean rm -f autoconfig.h config.log Makefile reconfig: @AUTOREMAKE@ # Automatically reconfigure whenever an autosetup file or one of the # make source files change. # # The "touch" is necessary to avoid a make loop due to a new upstream # feature in autosetup (GH 0a71e3c3b7) which rewrites *.in outputs only # if doing so will write different contents; otherwise, it leaves them # alone so the mtime doesn't change. This means that if you change one # our depdendencies besides Makefile.in, we'll reconfigure but Makefile # won't change, so this rule will remain out of date, so we'll reconfig # but Makefile won't change, so we'll reconfig but... endlessly. # # This is also why we repeat the reconfig target's command here instead # of delegating to it with "$(MAKE) reconfig": having children running # around interfering makes this failure mode even worse. Makefile: @srcdir@/Makefile.in $(SRCDIR)/main.mk @AUTODEPS@ @AUTOREMAKE@ touch @builddir@/Makefile |
Changes to VERSION.
1 |
2.3
|
| |
1 |
2.4
|
Changes to auto.def.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ... 187 188 189 190 191 192 193 194 195 196 197 198 199 200 ... 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
with-zlib:path|auto|tree => {Look for zlib in the given path, automatically, or in the source tree} with-exec-rel-paths=0 => {Enable relative paths for external diff/gdiff} with-legacy-mv-rm=0 => {Enable legacy behavior for mv/rm (skip checkout files)} with-th1-docs=0 => {Enable TH1 for embedded documentation pages} with-th1-hooks=0 => {Enable TH1 hooks for commands and web pages} with-tcl=path => {Enable Tcl integration, with Tcl in the specified path} with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism} with-tcl-private-stubs=0 => {Enable Tcl integration via private stubs mechanism} with-see=0 => {Enable the SQLite Encryption Extension (SEE)} internal-sqlite=1 => {Don't use the internal SQLite, use the system one} static=0 => {Link a static executable} fusefs=1 => {Disable the Fuse Filesystem} ................................................................................ # XXX: This will not work on all systems. define-append EXTRA_LDFLAGS -static msg-result "Trying to link statically" } else { define-append EXTRA_CFLAGS -DFOSSIL_DYNAMIC_BUILD=1 define FOSSIL_DYNAMIC_BUILD } # Helper for OpenSSL checking proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto}}} { msg-checking "Checking for $msg..." set rc 0 if {[is_mingw]} { lappend libs -lgdi32 -lwsock32 -lcrypt32 ................................................................................ cc-check-function-in-lib gethostbyname nsl if {![cc-check-function-in-lib socket {socket network}]} { # Last resort, may be Windows if {[is_mingw]} { define-append LIBS -lwsock32 } } cc-check-function-in-lib iconv iconv cc-check-functions utime cc-check-functions usleep cc-check-functions strchrnul # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE if {![cc-check-functions getloadavg]} { define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| > > > < |
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ... 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 ... 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
with-zlib:path|auto|tree => {Look for zlib in the given path, automatically, or in the source tree} with-exec-rel-paths=0 => {Enable relative paths for external diff/gdiff} with-legacy-mv-rm=0 => {Enable legacy behavior for mv/rm (skip checkout files)} with-th1-docs=0 => {Enable TH1 for embedded documentation pages} with-th1-hooks=0 => {Enable TH1 hooks for commands and web pages} with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism} with-tcl-private-stubs=0 => {Enable Tcl integration via private stubs mechanism} with-see=0 => {Enable the SQLite Encryption Extension (SEE)} internal-sqlite=1 => {Don't use the internal SQLite, use the system one} static=0 => {Link a static executable} fusefs=1 => {Disable the Fuse Filesystem} ................................................................................ # XXX: This will not work on all systems. define-append EXTRA_LDFLAGS -static msg-result "Trying to link statically" } else { define-append EXTRA_CFLAGS -DFOSSIL_DYNAMIC_BUILD=1 define FOSSIL_DYNAMIC_BUILD } # Check for libraries that need to be sorted out early cc-check-function-in-lib iconv iconv # Helper for OpenSSL checking proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto}}} { msg-checking "Checking for $msg..." set rc 0 if {[is_mingw]} { lappend libs -lgdi32 -lwsock32 -lcrypt32 ................................................................................ cc-check-function-in-lib gethostbyname nsl if {![cc-check-function-in-lib socket {socket network}]} { # Last resort, may be Windows if {[is_mingw]} { define-append LIBS -lwsock32 } } cc-check-functions utime cc-check-functions usleep cc-check-functions strchrnul # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE if {![cc-check-functions getloadavg]} { define FOSSIL_OMIT_LOAD_AVERAGE 1 |
Changes to autosetup/system.tcl.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
set cond [expr {!$cond}] } } continue } lappend result $line } writefile $out [string map $mapping [join $result \n]]\n msg-result "Created [relative-path $out] from [relative-path $template]" } # build/host tuples and cross-compilation prefix set build [opt-val build] define build_alias $build if {$build eq ""} { define build [config_guess] |
| < | > |
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
set cond [expr {!$cond}] } } continue } lappend result $line } write-if-changed $out [string map $mapping [join $result \n]]\n { msg-result "Created [relative-path $out] from [relative-path $template]" } } # build/host tuples and cross-compilation prefix set build [opt-val build] define build_alias $build if {$build eq ""} { define build [config_guess] |
Changes to skins/black_and_white/footer.txt.
1 2 3 4 |
<div class="footer">
Fossil $release_version $manifest_version $manifest_date
</div>
</body></html>
|
< |
1 2 3 |
<div class="footer"> Fossil $release_version $manifest_version $manifest_date </div> |
Changes to skins/black_and_white/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss"> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen"> </head> <body> <div class="header"> <div class="logo"> <img src="$logo_image_url" alt="logo"> <br />$<project_name> </div> <div class="title">$<title></div> <div class="status"><th1> |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="logo"> <img src="$logo_image_url" alt="logo"> <br />$<project_name> </div> <div class="title">$<title></div> <div class="status"><th1> |
Changes to skins/blitz/footer.txt.
1 2 3 4 5 6 7 8 9 10 11 12 |
</div> <!-- end div container --> </div> <!-- end div middle max-full-width --> <div class="footer"> <div class="container"> <div class="pull-right"> <a href="https://www.fossil-scm.org/">Fossil $release_version $manifest_version $manifest_date</a> </div> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s </div> </div> </body> </html> |
| | | | | | | | | | < < |
1 2 3 4 5 6 7 8 9 10 |
</div> <!-- end div container --> </div> <!-- end div middle max-full-width --> <div class="footer"> <div class="container"> <div class="pull-right"> <a href="https://www.fossil-scm.org/">Fossil $release_version $manifest_version $manifest_date</a> </div> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s </div> </div> |
Changes to skins/blitz/header.txt.
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 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head> <body> <div class="header"> <div class="container"> <!-- Header --> <div class="login pull-right"> <th1> if {[info exists login]} { html "<b>$login</b> — <a class='button' href='$home/login'>Logout</a>\n" } else { html "<a class='button' href='$home/login'>Login</a>\n" } </th1> <div> <h2><small>$title</small></h2> </div> </div> <div class='logo'> <img src='$logo_image_url' /> <th1> if {[anycap jor]} { html "<a class='rss' href='$home/timeline.rss'></a>" } </th1> </div> <!-- Main Menu --> <div class="mainmenu"> <ul> <th1> proc menulink {url name} { upvar current_page current upvar home home if {[string range $url 0 [string length $current]] eq "/$current"} { html "<li class='active'>" } else { html "<li>" |
< < < < < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | |
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 |
<div class="header"> <div class="container"> <!-- Header --> <div class="login pull-right"> <th1> if {[info exists login]} { html "<b>$login</b> — <a class='button' href='$home/login'>Logout</a>\n" } else { html "<a class='button' href='$home/login'>Login</a>\n" } </th1> <div> <h2><small>$title</small></h2> </div> </div> <div class='logo'> <img src='$logo_image_url' /> <th1> if {[anycap jor]} { html "<a class='rss' href='$home/timeline.rss'></a>" } </th1> </div> <!-- Main Menu --> <div class="mainmenu"> <ul> <th1> proc menulink {url name} { upvar current_page current upvar home home if {[string range $url 0 [string length $current]] eq "/$current"} { html "<li class='active'>" } else { html "<li>" |
Changes to skins/blitz_no_logo/footer.txt.
1 2 3 4 5 6 7 8 9 10 11 12 |
</div> <!-- end div container --> </div> <!-- end div middle max-full-width --> <div class="footer"> <div class="container"> <div class="pull-right"> <a href="https://www.fossil-scm.org/">Fossil $release_version $manifest_version $manifest_date</a> </div> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s </div> </div> </body> </html> |
| | | | | | | | | | < < |
1 2 3 4 5 6 7 8 9 10 |
</div> <!-- end div container --> </div> <!-- end div middle max-full-width --> <div class="footer"> <div class="container"> <div class="pull-right"> <a href="https://www.fossil-scm.org/">Fossil $release_version $manifest_version $manifest_date</a> </div> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s </div> </div> |
Changes to skins/blitz_no_logo/header.txt.
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 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head> <body> <div class="header"> <div class="container"> <div class="login pull-right"> <th1> if {[info exists login]} { html "<b>$login</b> — <a class='button' href='$home/login'>Logout</a>\n" } else { html "<a class='button' href='$home/login'>Login</a>\n" } </th1> </div> <div class='title'> <h1>$<project_name> <th1> if {[anycap jor]} { html "<a class='rss' href='$home/timeline.rss'></a>" } </th1> <small> $<title></small></h1> </div> <!-- Main Menu --> <div class="mainmenu"> <ul> <th1> proc menulink {url name} { upvar current_page current upvar home home if {[string range $url 0 [string length $current]] eq "/$current"} { html "<li class='active'>" } else { html "<li>" |
< < < < < < < < < | | | | | | | | | | | | | | | | | | | | | | | | |
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 |
<div class="header"> <div class="container"> <div class="login pull-right"> <th1> if {[info exists login]} { html "<b>$login</b> — <a class='button' href='$home/login'>Logout</a>\n" } else { html "<a class='button' href='$home/login'>Login</a>\n" } </th1> </div> <div class='title'> <h1>$<project_name> <th1> if {[anycap jor]} { html "<a class='rss' href='$home/timeline.rss'></a>" } </th1> <small> $<title></small></h1> </div> <!-- Main Menu --> <div class="mainmenu"> <ul> <th1> proc menulink {url name} { upvar current_page current upvar home home if {[string range $url 0 [string length $current]] eq "/$current"} { html "<li class='active'>" } else { html "<li>" |
Changes to skins/bootstrap/footer.txt.
32 33 34 35 36 37 38 39 |
var target = document.querySelector(
collapse.getAttribute('data-target')
);
target.classList.toggle('collapse');
target.classList.toggle('collapsed');
};
</script>
</body></html>
|
< |
32 33 34 35 36 37 38 |
var target = document.querySelector( collapse.getAttribute('data-target') ); target.classList.toggle('collapse'); target.classList.toggle('collapsed'); }; </script> |
Changes to skins/default/footer.txt.
1 2 3 4 5 6 |
<div class="footer">
This page was generated in about
<th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
Fossil $release_version $manifest_version $manifest_date
</div>
</body></html>
|
< |
1 2 3 4 5 |
<div class="footer"> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by Fossil $release_version $manifest_version $manifest_date </div> |
Changes to skins/default/header.txt.
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 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head> <body> <div class="header"> <div class="title"><h1>$<project_name></h1>$<title></div> <div class="status"><th1> if {[info exists login]} { html "$login — <a href='$home/login'>Logout</a>\n" } else { html "<a href='$home/login'>Login</a>\n" } </th1></div> </div> <div class="mainmenu"> <th1> proc menulink {url name} { upvar current_page current upvar home home if {[string range $url 0 [string length $current]] eq "/$current"} { html "<a href='$home$url' class='active'>$name</a>\n" } else { |
< < < < < < < < < < < | | | | | | | | | | < | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<div class="header"> <div class="title"><h1>$<project_name></h1>$<title></div> <div class="status"><th1> if {[info exists login]} { html "$login — <a href='$home/login'>Logout</a>\n" } else { html "<a href='$home/login'>Login</a>\n" } </th1></div> </div> <div class="mainmenu"> <th1> proc menulink {url name} { upvar current_page current upvar home home if {[string range $url 0 [string length $current]] eq "/$current"} { html "<a href='$home$url' class='active'>$name</a>\n" } else { |
Changes to skins/eagle/footer.txt.
18 19 20 21 22 23 24 25 |
This page was generated in about
<th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
<a href="$fossilUrl/">Fossil</a>
version $release_version $tclVersion
<a href="$fossilUrl/index.html/info/$version">$manifest_version</a>
<a href="$fossilUrl/index.html/timeline?c=$fossilDate&y=ci">$manifest_date</a>
</div>
</body></html>
|
< |
18 19 20 21 22 23 24 |
This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by <a href="$fossilUrl/">Fossil</a> version $release_version $tclVersion <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> <a href="$fossilUrl/index.html/timeline?c=$fossilDate&y=ci">$manifest_date</a> </div> |
Changes to skins/eagle/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head> <body> <div class="header"> <div class="logo"> <th1> ## ## NOTE: The purpose of this procedure is to take the base URL of the ## Fossil project and return the root of the entire web site using ## the same URI scheme as the base URL (e.g. http or https). |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="logo"> <th1> ## ## NOTE: The purpose of this procedure is to take the base URL of the ## Fossil project and return the root of the entire web site using ## the same URI scheme as the base URL (e.g. http or https). |
Changes to skins/enhanced1/footer.txt.
18 19 20 21 22 23 24 25 |
This page was generated in about
<th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
<a href="$fossilUrl/">Fossil</a>
version $release_version $tclVersion
<a href="$fossilUrl/index.html/info/$version">$manifest_version</a>
<a href="$fossilUrl/index.html/timeline?c=$fossilDate&y=ci">$manifest_date</a>
</div>
</body></html>
|
< |
18 19 20 21 22 23 24 |
This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by <a href="$fossilUrl/">Fossil</a> version $release_version $tclVersion <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> <a href="$fossilUrl/index.html/timeline?c=$fossilDate&y=ci">$manifest_date</a> </div> |
Changes to skins/enhanced1/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head> <body> <div class="header"> <div class="logo"> <th1> ## ## NOTE: The purpose of this procedure is to take the base URL of the ## Fossil project and return the root of the entire web site using ## the same URI scheme as the base URL (e.g. http or https). |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="logo"> <th1> ## ## NOTE: The purpose of this procedure is to take the base URL of the ## Fossil project and return the root of the entire web site using ## the same URI scheme as the base URL (e.g. http or https). |
Changes to skins/khaki/footer.txt.
1 2 3 4 |
<div class="footer">
Fossil $release_version $manifest_version $manifest_date
</div>
</body></html>
|
< |
1 2 3 |
<div class="footer"> Fossil $release_version $manifest_version $manifest_date </div> |
Changes to skins/khaki/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss"> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen"> </head> <body> <div class="header"> <div class="title">$<title></div> <div class="status"> <div class="logo">$<project_name></div><br/> <th1> if {[info exists login]} { puts "Logged in as $login" |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="title">$<title></div> <div class="status"> <div class="logo">$<project_name></div><br/> <th1> if {[info exists login]} { puts "Logged in as $login" |
Changes to skins/original/footer.txt.
1 2 3 4 5 6 |
<div class="footer">
This page was generated in about
<th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
Fossil $release_version $manifest_version $manifest_date
</div>
</body></html>
|
< |
1 2 3 4 5 |
<div class="footer"> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by Fossil $release_version $manifest_version $manifest_date </div> |
Changes to skins/original/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head> <body> <div class="header"> <div class="logo"> <img src="$logo_image_url" alt="logo" /> </div> <div class="title"><small>$<project_name></small><br />$<title></div> <div class="status"><th1> if {[info exists login]} { |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="logo"> <img src="$logo_image_url" alt="logo" /> </div> <div class="title"><small>$<project_name></small><br />$<title></div> <div class="status"><th1> if {[info exists login]} { |
Changes to skins/plain_gray/footer.txt.
1 2 3 4 |
<div class="footer">
Fossil $release_version $manifest_version $manifest_date
</div>
</body></html>
|
< |
1 2 3 |
<div class="footer"> Fossil $release_version $manifest_version $manifest_date </div> |
Changes to skins/plain_gray/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss"> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen"> </head> <body> <div class="header"> <div class="title"><small>$<project_name></small><br />$<title></div> <div class="status"><th1> if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="title"><small>$<project_name></small><br />$<title></div> <div class="status"><th1> if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" |
Changes to skins/rounded1/footer.txt.
1 2 3 4 |
<div class="footer">
Fossil $release_version $manifest_version $manifest_date
</div>
</body></html>
|
< |
1 2 3 |
<div class="footer"> Fossil $release_version $manifest_version $manifest_date </div> |
Changes to skins/rounded1/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss"> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen"> </head> <body> <div class="header"> <div class="logo"> <img src="$logo_image_url" alt="logo"> <br />$<project_name> </div> <div class="title">$<title></div> <div class="status"><th1> |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="logo"> <img src="$logo_image_url" alt="logo"> <br />$<project_name> </div> <div class="title">$<title></div> <div class="status"><th1> |
Changes to skins/xekri/css.txt.
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 |
/* color for capabilities, inherited by developer */
span.ueditInheritDeveloper {
color: #f00;
}
/* color for capabilities, inherited by reader */
span.ueditInheritReader {
color: black;
}
/* color for capabilities, inherited by anonymous */
span.ueditInheritAnonymous {
color: #00f;
}
|
| |
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 |
/* color for capabilities, inherited by developer */
span.ueditInheritDeveloper {
color: #f00;
}
/* color for capabilities, inherited by reader */
span.ueditInheritReader {
color: #ee0;
}
/* color for capabilities, inherited by anonymous */
span.ueditInheritAnonymous {
color: #00f;
}
|
Changes to skins/xekri/footer.txt.
3 4 5 6 7 8 9 10 11 |
<div class="page-time"> Generated in <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s </div> <div class="fossil-info"> Fossil v$release_version $manifest_version </div> </div> </body> </html> |
< < |
3 4 5 6 7 8 9 |
<div class="page-time"> Generated in <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s </div> <div class="fossil-info"> Fossil v$release_version $manifest_version </div> </div> |
Changes to skins/xekri/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head> <body> <div class="header"> <div class="logo"> <th1> ## ## NOTE: The purpose of this procedure is to take the base URL of the ## Fossil project and return the root of the entire web site using ## the same URI scheme as the base URL (e.g. http or https). |
< < < < < < < < < < |
1 2 3 4 5 6 7 |
<div class="header"> <div class="logo"> <th1> ## ## NOTE: The purpose of this procedure is to take the base URL of the ## Fossil project and return the root of the entire web site using ## the same URI scheme as the base URL (e.g. http or https). |
Changes to src/add.c.
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 ... 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 ... 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 ... 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 |
** --case-sensitive <BOOL> Override the case-sensitive setting. ** --dotfiles include files beginning with a dot (".") ** -f|--force Add files without prompting ** --ignore <CSG> Ignore unmanaged files matching patterns from ** the comma separated list of glob patterns. ** --clean <CSG> Also ignore files matching patterns from ** the comma separated list of glob patterns. ** --no-dir-symlinks Disables support for directory symlinks. ** ** See also: addremove, rm */ void add_cmd(void){ int i; /* Loop counter */ int vid; /* Currently checked out version */ int nRoot; /* Full path characters in g.zLocalRoot */ ................................................................................ ** ** Options: ** --soft Skip removing files from the checkout. ** This supersedes the --hard option. ** --hard Remove files from the checkout. ** --case-sensitive <BOOL> Override the case-sensitive setting. ** -n|--dry-run If given, display instead of run actions. ** --no-dir-symlinks Disables support for directory symlinks. ** ** See also: addremove, add */ void delete_cmd(void){ int i; int removeFiles; int dryRunFlag; ................................................................................ ** --case-sensitive <BOOL> Override the case-sensitive setting. ** --dotfiles Include files beginning with a dot (".") ** --ignore <CSG> Ignore unmanaged files matching patterns from ** the comma separated list of glob patterns. ** --clean <CSG> Also ignore files matching patterns from ** the comma separated list of glob patterns. ** -n|--dry-run If given, display instead of run actions. ** --no-dir-symlinks Disables support for directory symlinks. ** ** See also: add, rm */ void addremove_cmd(void){ Blob path; const char *zCleanFlag = find_option("clean",0,1); const char *zIgnoreFlag = find_option("ignore",0,1); ................................................................................ ** ** Options: ** --soft Skip moving files within the checkout. ** This supersedes the --hard option. ** --hard Move files within the checkout. ** --case-sensitive <BOOL> Override the case-sensitive setting. ** -n|--dry-run If given, display instead of run actions. ** --no-dir-symlinks Disables support for directory symlinks. ** ** See also: changes, status */ void mv_cmd(void){ int i; int vid; int moveFiles; |
< < < < |
274 275 276 277 278 279 280 281 282 283 284 285 286 287 ... 439 440 441 442 443 444 445 446 447 448 449 450 451 452 ... 620 621 622 623 624 625 626 627 628 629 630 631 632 633 ... 847 848 849 850 851 852 853 854 855 856 857 858 859 860 |
** --case-sensitive <BOOL> Override the case-sensitive setting. ** --dotfiles include files beginning with a dot (".") ** -f|--force Add files without prompting ** --ignore <CSG> Ignore unmanaged files matching patterns from ** the comma separated list of glob patterns. ** --clean <CSG> Also ignore files matching patterns from ** the comma separated list of glob patterns. ** ** See also: addremove, rm */ void add_cmd(void){ int i; /* Loop counter */ int vid; /* Currently checked out version */ int nRoot; /* Full path characters in g.zLocalRoot */ ................................................................................ ** ** Options: ** --soft Skip removing files from the checkout. ** This supersedes the --hard option. ** --hard Remove files from the checkout. ** --case-sensitive <BOOL> Override the case-sensitive setting. ** -n|--dry-run If given, display instead of run actions. ** ** See also: addremove, add */ void delete_cmd(void){ int i; int removeFiles; int dryRunFlag; ................................................................................ ** --case-sensitive <BOOL> Override the case-sensitive setting. ** --dotfiles Include files beginning with a dot (".") ** --ignore <CSG> Ignore unmanaged files matching patterns from ** the comma separated list of glob patterns. ** --clean <CSG> Also ignore files matching patterns from ** the comma separated list of glob patterns. ** -n|--dry-run If given, display instead of run actions. ** ** See also: add, rm */ void addremove_cmd(void){ Blob path; const char *zCleanFlag = find_option("clean",0,1); const char *zIgnoreFlag = find_option("ignore",0,1); ................................................................................ ** ** Options: ** --soft Skip moving files within the checkout. ** This supersedes the --hard option. ** --hard Move files within the checkout. ** --case-sensitive <BOOL> Override the case-sensitive setting. ** -n|--dry-run If given, display instead of run actions. ** ** See also: changes, status */ void mv_cmd(void){ int i; int vid; int moveFiles; |
Changes to src/blob.c.
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 |
}else{ z[--j] = z[i]; } } } /* ** Shell-escape the given string. Append the result to a blob. */ void shell_escape(Blob *pBlob, const char *zIn){ int n = blob_size(pBlob); int k = strlen(zIn); int i, c; char *z; for(i=0; (c = zIn[i])!=0; i++){ if( fossil_isspace(c) || c=='"' || (c=='\\' && zIn[i+1]!=0) ){ blob_appendf(pBlob, "\"%s\"", zIn); z = blob_buffer(pBlob); for(i=n+1; i<=n+k; i++){ if( z[i]=='"' ) z[i] = '_'; } return; } } blob_append(pBlob, zIn, -1); } /* ** A read(2)-like impl for the Blob class. Reads (copies) up to nLen ** bytes from pIn, starting at position pIn->iCursor, and copies them ** to pDest (which must be valid memory at least nLen bytes long). ** |
| > > > > > > > > > > > | < < | | > > > > > > > > > < < < < < > > > > > > | < > > > > > > > > |
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 |
}else{ z[--j] = z[i]; } } } /* ** pBlob is a shell command under construction. This routine safely ** appends argument zIn. ** ** The argument is escaped if it contains white space or other characters ** that need to be escaped for the shell. If zIn contains characters ** that cannot be safely escaped, then throw a fatal error. ** ** The argument is expected to a filename of some kinds. As shell commands ** commonly have command-line options that begin with "-" and since we ** do not want an attacker to be able to invoke these switches using ** filenames that begin with "-", if zIn begins with "-", prepend ** an additional "./". */ void blob_append_escaped_arg(Blob *pBlob, const char *zIn){ int i; char c; int needEscape = 0; int n = blob_size(pBlob); char *z = blob_buffer(pBlob); #if defined(_WIN32) const char cQuote = '"'; /* Use "..." quoting on windows */ #else const char cQuote = '\''; /* Use '...' quoting on unix */ #endif for(i=0; (c = zIn[i])!=0; i++){ if( c==cQuote || c=='\\' || c<' ' || c==';' || c=='*' || c=='?' || c=='[') { Blob bad; blob_token(pBlob, &bad); fossil_fatal("the [%s] argument to the \"%s\" command contains " "a character (ascii 0x%02x) that is a security risk", zIn, blob_str(&bad), c); } if( !needEscape && !fossil_isalnum(c) && c!='/' && c!='.' && c!='_' ){ needEscape = 1; } } if( n>0 && !fossil_isspace(z[n-1]) ){ blob_append(pBlob, " ", 1); } if( needEscape ) blob_append(pBlob, &cQuote, 1); if( zIn[0]=='-' ) blob_append(pBlob, "./", 2); blob_append(pBlob, zIn, -1); if( needEscape ) blob_append(pBlob, &cQuote, 1); } /* ** A read(2)-like impl for the Blob class. Reads (copies) up to nLen ** bytes from pIn, starting at position pIn->iCursor, and copies them ** to pDest (which must be valid memory at least nLen bytes long). ** |
Changes to src/branch.c.
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
fossil_fatal("trouble committing manifest: %s", g.zErrMsg); } db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid); if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){ fossil_fatal("%s", g.zErrMsg); } assert( blob_is_reset(&branch) ); content_deltify(rootid, brid, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid); fossil_print("New branch: %s\n", zUuid); if( g.argc==3 ){ fossil_print( "\n" "Note: the local check-out has not been updated to the new\n" " branch. To begin working on the new branch, do this:\n" ................................................................................ Stmt q; double rNow; int show_colors = PB("colors"); login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } style_header("Branches"); style_adunit_config(ADUNIT_RIGHT_OK); style_submenu_checkbox("colors", "Use Branch Colors", 0); login_anonymous_available(); db_prepare(&q, brlistQuery/*works-like:""*/); rNow = db_double(0.0, "SELECT julianday('now')"); @ <div class="brlist"><table id="branchlisttable"> @ <thead><tr> @ <th>Branch Name</th> |
|
|
|
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
fossil_fatal("trouble committing manifest: %s", g.zErrMsg); } db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid); if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){ fossil_fatal("%s", g.zErrMsg); } assert( blob_is_reset(&branch) ); content_deltify(rootid, &brid, 1, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid); fossil_print("New branch: %s\n", zUuid); if( g.argc==3 ){ fossil_print( "\n" "Note: the local check-out has not been updated to the new\n" " branch. To begin working on the new branch, do this:\n" ................................................................................ Stmt q; double rNow; int show_colors = PB("colors"); login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } style_header("Branches"); style_adunit_config(ADUNIT_RIGHT_OK); style_submenu_checkbox("colors", "Use Branch Colors", 0, 0); login_anonymous_available(); db_prepare(&q, brlistQuery/*works-like:""*/); rNow = db_double(0.0, "SELECT julianday('now')"); @ <div class="brlist"><table id="branchlisttable"> @ <thead><tr> @ <th>Branch Name</th> |
Changes to src/browse.c.
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 |
if( p->pChild!=0 && p->nFullName>nD ) nFile++; } zObjType = "Folders"; }else{ zObjType = "Files"; } style_submenu_checkbox("nofiles", "Folders Only", 0); if( zCI ){ @ <h2>%s(zObjType) from if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){ @ "%h(zCI)" } @ [%z(href("vinfo?name=%!S",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname)) |
| |
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 |
if( p->pChild!=0 && p->nFullName>nD ) nFile++;
}
zObjType = "Folders";
}else{
zObjType = "Files";
}
style_submenu_checkbox("nofiles", "Folders Only", 0, 0);
if( zCI ){
@ <h2>%s(zObjType) from
if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
@ "%h(zCI)"
}
@ [%z(href("vinfo?name=%!S",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))
|
Changes to src/checkin.c.
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 ... 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 ... 854 855 856 857 858 859 860 861 862 863 864 865 866 867 ... 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 ... 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 ... 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 ... 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 .... 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 .... 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 .... 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 |
** --rel-paths Display pathnames relative to the current working ** directory. ** --hash Verify file status using hashing rather than ** relying on file mtimes. ** --case-sensitive <BOOL> Override case-sensitive setting. ** --dotfiles Include unmanaged files beginning with a dot. ** --ignore <CSG> Ignore unmanaged files matching CSG glob patterns. ** --no-dir-symlinks Disables support for directory symlinks. ** ** Options specific to the changes command: ** --header Identify the repository if report is non-empty. ** -v|--verbose Say "(none)" if the change report is empty. ** --classify Start each line with the file's change type. ** --no-classify Do not print file change types. ** ................................................................................ ** ** Options: ** --abs-paths Display absolute pathnames. ** --case-sensitive <BOOL> override case-sensitive setting ** --dotfiles include files beginning with a dot (".") ** --header Identify the repository if there are extras ** --ignore <CSG> ignore files matching patterns from the argument ** --no-dir-symlinks Disables support for directory symlinks. ** --rel-paths Display pathnames relative to the current working ** directory. ** ** See also: changes, clean, status */ void extras_cmd(void){ Blob report = BLOB_INITIALIZER; ................................................................................ /* We should be done with options.. */ verify_all_options(); if( zIgnoreFlag==0 ){ zIgnoreFlag = db_get("ignore-glob", 0); } pIgnore = glob_create(zIgnoreFlag); locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore); glob_free(pIgnore); blob_zero(&report); status_report(&report, flags); if( blob_size(&report) ){ if( showHdr ){ ................................................................................ ** ever be deleted. Files and subdirectories whose names begin with "." ** are automatically ignored unless the --dotfiles option is used. ** ** The default values for --clean, --ignore, and --keep are determined by ** the (versionable) clean-glob, ignore-glob, and keep-glob settings. ** ** The --verily option ignores the keep-glob and ignore-glob settings and ** turns on the options --force, --emptydirs, --dotfiles, --disable-undo, ** and --no-dir-symlinks. Use the --verily option when you really want ** to clean up everything. Extreme care should be exercised when using ** the --verily option. ** ** Options: ** --allckouts Check for empty directories within any checkouts ** that may be nested within the current one. This ** option should be used with great care because the ** empty-dirs setting (and other applicable settings) ** belonging to the other repositories, if any, will ................................................................................ ** that were removed will be removed as well. ** -f|--force Remove files without prompting. ** -i|--prompt Prompt before removing each file. This option ** implies the --disable-undo option. ** -x|--verily WARNING: Removes everything that is not a managed ** file or the repository itself. This option ** implies the --force, --emptydirs, --dotfiles, and ** --disable-undo, and --no-dir-symlinks options. ** Furthermore, it completely disregards the keep-glob ** and ignore-glob settings. However, it does honor ** the --ignore and --keep options. ** --clean <CSG> WARNING: Never prompt to delete any files matching ** this comma separated list of glob patterns. Also, ** deletions of any files matching this pattern list ** cannot be undone. ................................................................................ ** comma separated list of glob patterns. ** --keep <CSG> Keep files matching this comma separated ** list of glob patterns. ** -n|--dry-run Delete nothing, but display what would have been ** deleted. ** --no-prompt This option disables prompting the user for input ** and assumes an answer of 'No' for every question. ** --no-dir-symlinks Disables support for directory symlinks. ** --temp Remove only Fossil-generated temporary files. ** -v|--verbose Show all files as they are removed. ** ** See also: addremove, extras, status */ void clean_cmd(void){ int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; ................................................................................ db_must_be_within_tree(); if( find_option("verily","x",0)!=0 ){ verilyFlag = allFileFlag = allDirFlag = 1; emptyDirsFlag = 1; disableUndo = 1; scanFlags |= SCAN_ALL; zCleanFlag = 0; g.fNoDirSymlinks = 1; /* Forbid symlink directory traversal. */ g.allowSymlinks = 1; /* Treat symlink files as content. */ } if( zIgnoreFlag==0 && !verilyFlag ){ zIgnoreFlag = db_get("ignore-glob", 0); } if( zKeepFlag==0 && !verilyFlag ){ zKeepFlag = db_get("keep-glob", 0); } ................................................................................ } if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL; verify_all_options(); pIgnore = glob_create(zIgnoreFlag); pKeep = glob_create(zKeepFlag); pClean = glob_create(zCleanFlag); nRoot = (int)strlen(g.zLocalRoot); if( !dirsOnlyFlag ){ Stmt q; Blob repo; if( !dryRunFlag && !disableUndo ) undo_begin(); locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore); db_prepare(&q, "SELECT %Q || pathname FROM sfile" ................................................................................ fossil_print("possible unresolved merge conflict in %s\n", blob_str(&fname)); blob_reset(&fname); } nrid = content_put(&content); blob_reset(&content); if( rid>0 ){ content_deltify(rid, nrid, 0); } db_multi_exec("UPDATE vfile SET mrid=%d, rid=%d WHERE id=%d", nrid,nrid,id); db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); } db_finalize(&q); if( nConflict && !allowConflict ){ fossil_fatal("abort due to unresolved merge conflicts; " ................................................................................ } db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); if( manifest_crosslink(nvid, &manifest, dryRunFlag ? MC_NONE : MC_PERMIT_HOOKS)==0 ){ fossil_fatal("%s", g.zErrMsg); } assert( blob_is_reset(&manifest) ); content_deltify(vid, nvid, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid" " WHERE id=-4"); while( db_step(&q)==SQLITE_ROW ){ const char *zIntegrateUuid = db_column_text(&q, 0); if( is_a_leaf(db_column_int(&q, 1)) ){ |
< < > > | | | < | < < < > > | | |
415 416 417 418 419 420 421 422 423 424 425 426 427 428 ... 823 824 825 826 827 828 829 830 831 832 833 834 835 836 ... 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 ... 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 ... 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 ... 947 948 949 950 951 952 953 954 955 956 957 958 959 960 ... 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 .... 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 .... 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 .... 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 |
** --rel-paths Display pathnames relative to the current working ** directory. ** --hash Verify file status using hashing rather than ** relying on file mtimes. ** --case-sensitive <BOOL> Override case-sensitive setting. ** --dotfiles Include unmanaged files beginning with a dot. ** --ignore <CSG> Ignore unmanaged files matching CSG glob patterns. ** ** Options specific to the changes command: ** --header Identify the repository if report is non-empty. ** -v|--verbose Say "(none)" if the change report is empty. ** --classify Start each line with the file's change type. ** --no-classify Do not print file change types. ** ................................................................................ ** ** Options: ** --abs-paths Display absolute pathnames. ** --case-sensitive <BOOL> override case-sensitive setting ** --dotfiles include files beginning with a dot (".") ** --header Identify the repository if there are extras ** --ignore <CSG> ignore files matching patterns from the argument ** --rel-paths Display pathnames relative to the current working ** directory. ** ** See also: changes, clean, status */ void extras_cmd(void){ Blob report = BLOB_INITIALIZER; ................................................................................ /* We should be done with options.. */ verify_all_options(); if( zIgnoreFlag==0 ){ zIgnoreFlag = db_get("ignore-glob", 0); } pIgnore = glob_create(zIgnoreFlag); /* Always consider symlinks. */ g.allowSymlinks = db_allow_symlinks_by_default(); locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore); glob_free(pIgnore); blob_zero(&report); status_report(&report, flags); if( blob_size(&report) ){ if( showHdr ){ ................................................................................ ** ever be deleted. Files and subdirectories whose names begin with "." ** are automatically ignored unless the --dotfiles option is used. ** ** The default values for --clean, --ignore, and --keep are determined by ** the (versionable) clean-glob, ignore-glob, and keep-glob settings. ** ** The --verily option ignores the keep-glob and ignore-glob settings and ** turns on --force, --emptydirs, --dotfiles, and --disable-undo. Use the ** --verily option when you really want to clean up everything. Extreme ** care should be exercised when using the --verily option. ** ** Options: ** --allckouts Check for empty directories within any checkouts ** that may be nested within the current one. This ** option should be used with great care because the ** empty-dirs setting (and other applicable settings) ** belonging to the other repositories, if any, will ................................................................................ ** that were removed will be removed as well. ** -f|--force Remove files without prompting. ** -i|--prompt Prompt before removing each file. This option ** implies the --disable-undo option. ** -x|--verily WARNING: Removes everything that is not a managed ** file or the repository itself. This option ** implies the --force, --emptydirs, --dotfiles, and ** --disable-undo options. ** Furthermore, it completely disregards the keep-glob ** and ignore-glob settings. However, it does honor ** the --ignore and --keep options. ** --clean <CSG> WARNING: Never prompt to delete any files matching ** this comma separated list of glob patterns. Also, ** deletions of any files matching this pattern list ** cannot be undone. ................................................................................ ** comma separated list of glob patterns. ** --keep <CSG> Keep files matching this comma separated ** list of glob patterns. ** -n|--dry-run Delete nothing, but display what would have been ** deleted. ** --no-prompt This option disables prompting the user for input ** and assumes an answer of 'No' for every question. ** --temp Remove only Fossil-generated temporary files. ** -v|--verbose Show all files as they are removed. ** ** See also: addremove, extras, status */ void clean_cmd(void){ int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; ................................................................................ db_must_be_within_tree(); if( find_option("verily","x",0)!=0 ){ verilyFlag = allFileFlag = allDirFlag = 1; emptyDirsFlag = 1; disableUndo = 1; scanFlags |= SCAN_ALL; zCleanFlag = 0; } if( zIgnoreFlag==0 && !verilyFlag ){ zIgnoreFlag = db_get("ignore-glob", 0); } if( zKeepFlag==0 && !verilyFlag ){ zKeepFlag = db_get("keep-glob", 0); } ................................................................................ } if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL; verify_all_options(); pIgnore = glob_create(zIgnoreFlag); pKeep = glob_create(zKeepFlag); pClean = glob_create(zCleanFlag); nRoot = (int)strlen(g.zLocalRoot); /* Always consider symlinks. */ g.allowSymlinks = db_allow_symlinks_by_default(); if( !dirsOnlyFlag ){ Stmt q; Blob repo; if( !dryRunFlag && !disableUndo ) undo_begin(); locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore); db_prepare(&q, "SELECT %Q || pathname FROM sfile" ................................................................................ fossil_print("possible unresolved merge conflict in %s\n", blob_str(&fname)); blob_reset(&fname); } nrid = content_put(&content); blob_reset(&content); if( rid>0 ){ content_deltify(rid, &nrid, 1, 0); } db_multi_exec("UPDATE vfile SET mrid=%d, rid=%d WHERE id=%d", nrid,nrid,id); db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); } db_finalize(&q); if( nConflict && !allowConflict ){ fossil_fatal("abort due to unresolved merge conflicts; " ................................................................................ } db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); if( manifest_crosslink(nvid, &manifest, dryRunFlag ? MC_NONE : MC_PERMIT_HOOKS)==0 ){ fossil_fatal("%s", g.zErrMsg); } assert( blob_is_reset(&manifest) ); content_deltify(vid, &nvid, 1, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid" " WHERE id=-4"); while( db_step(&q)==SQLITE_ROW ){ const char *zIntegrateUuid = db_column_text(&q, 0); if( is_a_leaf(db_column_int(&q, 1)) ){ |
Changes to src/clone.c.
291 292 293 294 295 296 297 |
** options). */ void clone_ssh_db_set_options(void){ if( g.zSshCmd && g.zSshCmd[0] ){ db_set("ssh-command", g.zSshCmd, 0); } } |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
** options). */ void clone_ssh_db_set_options(void){ if( g.zSshCmd && g.zSshCmd[0] ){ db_set("ssh-command", g.zSshCmd, 0); } } /* ** WEBPAGE: download ** ** Provide a simple page that enables newbies to download the latest tarball or ** ZIP archive, and provides instructions on how to clone. */ void download_page(void){ login_check_credentials(); style_header("Download Page"); if( !g.perm.Zip ){ @ <p>Bummer. You do not have permission to download. if( g.zLogin==0 || g.zLogin[0]==0 ){ @ Maybe it would work better if you @ <a href="../login">logged in</a>. }else{ @ Contact the site administrator and ask them to give @ you "Download Zip" privileges. } }else{ const char *zDLTag = db_get("download-tag","trunk"); const char *zNm = db_get("short-project-name","download"); char *zUrl = href("%R/zip/%t.zip?uuid=%t", zNm, zDLTag); @ <p>ZIP Archive: %z(zUrl)%h(zNm).zip</a> zUrl = href("%R/tarball/%t.tar.gz?uuid=%t", zNm, zDLTag); @ <p>Tarball: %z(zUrl)%h(zNm).tar.gz</a> } if( !g.perm.Clone ){ @ <p>You are not authorized to clone this repository. if( g.zLogin==0 || g.zLogin[0]==0 ){ @ Maybe you would be able to clone if you @ <a href="../login">logged in</a>. }else{ @ Contact the site administrator and ask them to give @ you "Clone" privileges in order to clone. } }else{ const char *zNm = db_get("short-project-name","clone"); @ <p>Clone the repository using this command: @ <blockquote><pre> @ fossil clone %s(g.zBaseURL) %h(zNm).fossil @ </pre></blockquote> } style_footer(); } |
Changes to src/configure.c.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 .. 65 66 67 68 69 70 71 72 73 74 75 76 77 78 ... 152 153 154 155 156 157 158 159 160 161 162 163 164 165 ... 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 ... 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 ... 512 513 514 515 516 517 518 519 520 521 522 523 524 525 ... 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 ... 755 756 757 758 759 760 761 762 763 764 765 766 767 768 ... 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 ... 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 ... 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 ... 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 |
#define CONFIGSET_SKIN 0x000002 /* WWW interface appearance */ #define CONFIGSET_TKT 0x000004 /* Ticket configuration */ #define CONFIGSET_PROJ 0x000008 /* Project name */ #define CONFIGSET_SHUN 0x000010 /* Shun settings */ #define CONFIGSET_USER 0x000020 /* The USER table */ #define CONFIGSET_ADDR 0x000040 /* The CONCEALED table */ #define CONFIGSET_XFER 0x000080 /* Transfer configuration */ #define CONFIGSET_ALL 0x0000ff /* Everything */ #define CONFIGSET_OVERWRITE 0x100000 /* Causes overwrite instead of merge */ #define CONFIGSET_OLDFORMAT 0x200000 /* Use the legacy format */ /* ** This mask is used for the common TH1 configuration settings (i.e. those ** that are not specific to one particular subsystem, such as the transfer ** subsystem). */ #define CONFIGSET_TH1 (CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER) ................................................................................ { "/skin", CONFIGSET_SKIN | CONFIGSET_CSS, "Web interface appearance settings" }, { "/css", CONFIGSET_CSS, "Style sheet" }, { "/shun", CONFIGSET_SHUN, "List of shunned artifacts" }, { "/ticket", CONFIGSET_TKT, "Ticket setup", }, { "/user", CONFIGSET_USER, "Users and privilege settings" }, { "/xfer", CONFIGSET_XFER, "Transfer setup", }, { "/all", CONFIGSET_ALL, "All of the above" }, }; /* ** The following is a list of settings that we are willing to ** transfer. ................................................................................ { "@user", CONFIGSET_USER }, { "@concealed", CONFIGSET_ADDR }, { "@shun", CONFIGSET_SHUN }, { "xfer-common-script", CONFIGSET_XFER }, { "xfer-push-script", CONFIGSET_XFER }, { "xfer-commit-script", CONFIGSET_XFER }, { "xfer-ticket-script", CONFIGSET_XFER }, }; static int iConfig = 0; ................................................................................ ** Return name of first configuration property matching the given mask. */ const char *configure_first_name(int iMask){ iConfig = 0; return configure_next_name(iMask); } const char *configure_next_name(int iMask){ if( iMask & CONFIGSET_OLDFORMAT ){ while( iConfig<count(aConfig) ){ if( aConfig[iConfig].groupMask & iMask ){ return aConfig[iConfig++].zName; }else{ iConfig++; } } }else{ if( iConfig==0 && (iMask & CONFIGSET_ALL)==CONFIGSET_ALL ){ iConfig = count(aGroupName); return "/all"; } while( iConfig<count(aGroupName)-1 ){ if( aGroupName[iConfig].groupMask & iMask ){ return aGroupName[iConfig++].zName; }else{ iConfig++; } } } return 0; } /* ** Return a pointer to a string that contains the RHS of an IN operator ................................................................................ } if( !g.perm.RdAddr ){ m &= ~CONFIGSET_ADDR; } return m; } } return 0; } /* ** zName is one of the special configuration names that refers to an entire ** table rather than a single entry in CONFIG. Special names are "@reportfmt" ** and "@shun" and "@user". This routine writes SQL text into pOut that when ** evaluated will populate the corresponding table with data. */ void configure_render_special_name(const char *zName, Blob *pOut){ Stmt q; if( fossil_strcmp(zName, "@shun")==0 ){ db_prepare(&q, "SELECT uuid FROM shun"); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(pOut, "INSERT OR IGNORE INTO shun VALUES('%s');\n", db_column_text(&q, 0) ); } db_finalize(&q); }else if( fossil_strcmp(zName, "@reportfmt")==0 ){ db_prepare(&q, "SELECT title, cols, sqlcode FROM reportfmt"); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(pOut, "INSERT INTO _xfer_reportfmt(title,cols,sqlcode)" " VALUES(%Q,%Q,%Q);\n", db_column_text(&q, 0), db_column_text(&q, 1), db_column_text(&q, 2) ); } db_finalize(&q); }else if( fossil_strcmp(zName, "@user")==0 ){ db_prepare(&q, "SELECT login, CASE WHEN length(pw)==40 THEN pw END," " cap, info, quote(photo) FROM user"); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(pOut, "INSERT INTO _xfer_user(login,pw,cap,info,photo)" " VALUES(%Q,%Q,%Q,%Q,%s);\n", db_column_text(&q, 0), db_column_text(&q, 1), db_column_text(&q, 2), db_column_text(&q, 3), db_column_text(&q, 4) ); } db_finalize(&q); }else if( fossil_strcmp(zName, "@concealed")==0 ){ db_prepare(&q, "SELECT hash, content FROM concealed"); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(pOut, "INSERT OR IGNORE INTO concealed(hash,content)" " VALUES(%Q,%Q);\n", db_column_text(&q, 0), db_column_text(&q, 1) ); } db_finalize(&q); } } /* ** Two SQL functions: ** ** config_is_reset(int) ** config_reset(int) ** ** The config_is_reset() function takes the integer valued argument and ** ANDs it against the static variable "configHasBeenReset" below. The ** function returns TRUE or FALSE depending on the result depending on ** whether or not the corresponding configuration table has been reset. The ** config_reset() function adds the bits to "configHasBeenReset" that ** are given in the argument. ** ** These functions are used below in the WHEN clause of a trigger to ** get the trigger to fire exactly once. */ static int configHasBeenReset = 0; static void config_is_reset_function( sqlite3_context *context, int argc, sqlite3_value **argv ){ int m = sqlite3_value_int(argv[0]); sqlite3_result_int(context, (configHasBeenReset&m)!=0 ); } static void config_reset_function( sqlite3_context *context, int argc, sqlite3_value **argv ){ int m = sqlite3_value_int(argv[0]); configHasBeenReset |= m; } /* ** Create the temporary _xfer_reportfmt and _xfer_user tables that are ** necessary in order to evaluate the SQL text generated by the ** configure_render_special_name() routine. ** ** If replaceFlag is true, then the setup is such that the content in ** the SQL text will completely replace the current repository configuration. ** If replaceFlag is false, then the SQL text will be merged with the ** existing configuration. When merging, existing values take priority ** over SQL text values. */ void configure_prepare_to_receive(int replaceFlag){ static const char zSQL1[] = @ CREATE TEMP TABLE _xfer_reportfmt( @ rn integer primary key, -- Report number @ owner text, -- Owner of this report format (not used) @ title text UNIQUE ON CONFLICT IGNORE, -- Title of this report @ cols text, -- A color-key specification @ sqlcode text -- An SQL SELECT statement for this report @ ); @ CREATE TEMP TABLE _xfer_user( @ uid INTEGER PRIMARY KEY, -- User ID @ login TEXT UNIQUE ON CONFLICT IGNORE, -- login name of the user @ pw TEXT, -- password @ cap TEXT, -- Capabilities of this user @ cookie TEXT, -- WWW login cookie @ ipaddr TEXT, -- IP address for which cookie is valid @ cexpire DATETIME, -- Time when cookie expires @ info TEXT, -- contact information @ photo BLOB -- JPEG image of this user @ ); @ INSERT INTO _xfer_reportfmt @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt; @ INSERT INTO _xfer_user @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user; ; assert( strchr(zSQL1,'%')==0 ); db_multi_exec(zSQL1 /*works-like:""*/); /* When the replace flag is set, add triggers that run the first time ** that new data is seen. The triggers run only once and delete all the ** existing data. */ if( replaceFlag ){ static const char zSQL2[] = @ CREATE TRIGGER _xfer_r1 BEFORE INSERT ON _xfer_reportfmt @ WHEN NOT config_is_reset(2) BEGIN @ DELETE FROM _xfer_reportfmt; @ SELECT config_reset(2); @ END; @ CREATE TRIGGER _xfer_r2 BEFORE INSERT ON _xfer_user @ WHEN NOT config_is_reset(16) BEGIN @ DELETE FROM _xfer_user; @ SELECT config_reset(16); @ END; @ CREATE TEMP TRIGGER _xfer_r3 BEFORE INSERT ON shun @ WHEN NOT config_is_reset(8) BEGIN @ DELETE FROM shun; @ SELECT config_reset(8); @ END; ; sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0, config_is_reset_function, 0, 0); sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0, config_reset_function, 0, 0); configHasBeenReset = 0; assert( strchr(zSQL2,'%')==0 ); db_multi_exec(zSQL2 /*works-like:""*/); } } /* ** After receiving configuration data, call this routine to transfer ** the results into the main database. */ void configure_finalize_receive(void){ static const char zSQL[] = @ DELETE FROM user; @ INSERT INTO user SELECT * FROM _xfer_user; @ DELETE FROM reportfmt; @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt; @ DROP TABLE _xfer_user; @ DROP TABLE _xfer_reportfmt; ; assert( strchr(zSQL,'%')==0 ); db_multi_exec(zSQL /*works-like:""*/); } /* ** Mask of modified configuration sets */ static int rebuildMask = 0; /* ................................................................................ ** /concealed $MTIME $HASH content $VALUE ** ** OLD FORMAT: ** ** The old format is retained for backwards compatibility, but is deprecated. ** The cutover from old format to new was on 2011-04-25. After sufficient ** time has passed, support for the old format will be removed. ** ** zName is either the NAME of an element of the CONFIG table, or else ** one of the special names "@shun", "@reportfmt", "@user", or "@concealed". ** If zName is a CONFIG table name, then CONTENT replaces (overwrites) the ** element in the CONFIG table. For one of the @-labels, CONTENT is raw ** SQL that is evaluated. Note that the raw SQL in CONTENT might not ** insert directly into the target table but might instead use a proxy ................................................................................ blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s", aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/, azToken[0]/*safe-for-%s*/); db_multi_exec("%s", blob_sql_text(&sql)); } blob_reset(&sql); rebuildMask |= thisMask; }else{ /* Otherwise, the old format */ if( (configure_is_exportable(zName) & groupMask)==0 ) return; if( fossil_strcmp(zName, "logo-image")==0 ){ Stmt ins; db_prepare(&ins, "REPLACE INTO config(name, value, mtime) VALUES(:name, :value, now())" ); db_bind_text(&ins, ":name", zName); db_bind_blob(&ins, ":value", pContent); db_step(&ins); db_finalize(&ins); }else if( zName[0]=='@' ){ /* Notice that we are evaluating arbitrary SQL received from the ** client. But this can only happen if the client has authenticated ** as an administrator, so presumably we trust the client at this ** point. */ db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/); }else{ db_multi_exec( "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())", zName, blob_str(pContent) ); } } } /* ** Process a file full of "config" cards. */ void configure_receive_all(Blob *pIn, int groupMask){ ................................................................................ ); blob_appendf(pOut, "config /concealed %d\n%s\n", blob_size(&rec), blob_str(&rec)); nCard++; blob_reset(&rec); } db_finalize(&q); } db_prepare(&q, "SELECT mtime, quote(name), quote(value) FROM config" " WHERE name=:name AND mtime>=%lld", iStart); for(ii=0; ii<count(aConfig); ii++){ if( (aConfig[ii].groupMask & groupMask)!=0 && aConfig[ii].zName[0]!='@' ){ db_bind_text(&q, ":name", aConfig[ii].zName); while( db_step(&q)==SQLITE_ROW ){ ................................................................................ ** ** Where METHOD is one of: export import merge pull push reset. All methods ** accept the -R or --repository option to specify a repository. ** ** %fossil configuration export AREA FILENAME ** ** Write to FILENAME exported configuration information for AREA. ** AREA can be one of: all email project shun skin ticket user ** ** %fossil configuration import FILENAME ** ** Read a configuration from FILENAME, overwriting the current ** configuration. ** ** %fossil configuration merge FILENAME ................................................................................ ** the current configuration. Existing values take priority over ** values read from FILENAME. ** ** %fossil configuration pull AREA ?URL? ** ** Pull and install the configuration from a different server ** identified by URL. If no URL is specified, then the default ** server is used. Use the --legacy option for the older protocol ** (when talking to servers compiled prior to 2011-04-27.) Use ** the --overwrite flag to completely replace local settings with ** content received from URL. ** ** %fossil configuration push AREA ?URL? ** ** Push the local configuration into the remote server identified ** by URL. Admin privilege is required on the remote server for ** this to work. When the same record exists both locally and on ** the remote end, the one that was most recently changed wins. ** Use the --legacy flag when talking to older servers. ** ** %fossil configuration reset AREA ** ** Restore the configuration to the default. AREA as above. ** ** %fossil configuration sync AREA ?URL? ** ................................................................................ }else if( strncmp(zMethod, "pull", n)==0 || strncmp(zMethod, "push", n)==0 || strncmp(zMethod, "sync", n)==0 ){ int mask; const char *zServer = 0; int legacyFlag = 0; int overwriteFlag = 0; if( zMethod[0]!='s' ) legacyFlag = find_option("legacy",0,0)!=0; if( strncmp(zMethod,"pull",n)==0 ){ overwriteFlag = find_option("overwrite",0,0)!=0; } url_proxy_options(); if( g.argc!=4 && g.argc!=5 ){ usage(mprintf("%s AREA ?URL?", zMethod)); } ................................................................................ if( g.argc==5 ){ zServer = g.argv[4]; } url_parse(zServer, URL_PROMPT_PW); if( g.url.protocol==0 ) fossil_fatal("no server URL specified"); user_select(); url_enable_proxy("via proxy: "); if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; if( strncmp(zMethod, "push", n)==0 ){ client_sync(0,0,(unsigned)mask); }else if( strncmp(zMethod, "pull", n)==0 ){ client_sync(0,(unsigned)mask,0); }else{ client_sync(0,(unsigned)mask,(unsigned)mask); |
> | < > > > < < < < < < < < < | | | | | | | | | < > | | > | < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > | | < | < < < < < |
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 .. 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ... 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 ... 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 ... 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 ... 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 ... 432 433 434 435 436 437 438 439 440 441 442 443 444 445 ... 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 ... 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 ... 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 ... 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 ... 760 761 762 763 764 765 766 767 768 769 770 771 772 773 |
#define CONFIGSET_SKIN 0x000002 /* WWW interface appearance */ #define CONFIGSET_TKT 0x000004 /* Ticket configuration */ #define CONFIGSET_PROJ 0x000008 /* Project name */ #define CONFIGSET_SHUN 0x000010 /* Shun settings */ #define CONFIGSET_USER 0x000020 /* The USER table */ #define CONFIGSET_ADDR 0x000040 /* The CONCEALED table */ #define CONFIGSET_XFER 0x000080 /* Transfer configuration */ #define CONFIGSET_ALIAS 0x000100 /* URL Aliases */ #define CONFIGSET_ALL 0x0001ff /* Everything */ #define CONFIGSET_OVERWRITE 0x100000 /* Causes overwrite instead of merge */ /* ** This mask is used for the common TH1 configuration settings (i.e. those ** that are not specific to one particular subsystem, such as the transfer ** subsystem). */ #define CONFIGSET_TH1 (CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER) ................................................................................ { "/skin", CONFIGSET_SKIN | CONFIGSET_CSS, "Web interface appearance settings" }, { "/css", CONFIGSET_CSS, "Style sheet" }, { "/shun", CONFIGSET_SHUN, "List of shunned artifacts" }, { "/ticket", CONFIGSET_TKT, "Ticket setup", }, { "/user", CONFIGSET_USER, "Users and privilege settings" }, { "/xfer", CONFIGSET_XFER, "Transfer setup", }, { "/alias", CONFIGSET_ALIAS, "URL Aliases", }, { "/all", CONFIGSET_ALL, "All of the above" }, }; /* ** The following is a list of settings that we are willing to ** transfer. ................................................................................ { "@user", CONFIGSET_USER }, { "@concealed", CONFIGSET_ADDR }, { "@shun", CONFIGSET_SHUN }, { "@alias", CONFIGSET_ALIAS }, { "xfer-common-script", CONFIGSET_XFER }, { "xfer-push-script", CONFIGSET_XFER }, { "xfer-commit-script", CONFIGSET_XFER }, { "xfer-ticket-script", CONFIGSET_XFER }, }; static int iConfig = 0; ................................................................................ ** Return name of first configuration property matching the given mask. */ const char *configure_first_name(int iMask){ iConfig = 0; return configure_next_name(iMask); } const char *configure_next_name(int iMask){ if( iConfig==0 && (iMask & CONFIGSET_ALL)==CONFIGSET_ALL ){ iConfig = count(aGroupName); return "/all"; } while( iConfig<count(aGroupName)-1 ){ if( aGroupName[iConfig].groupMask & iMask ){ return aGroupName[iConfig++].zName; }else{ iConfig++; } } return 0; } /* ** Return a pointer to a string that contains the RHS of an IN operator ................................................................................ } if( !g.perm.RdAddr ){ m &= ~CONFIGSET_ADDR; } return m; } } if( strncmp(zName, "walias:/", 8)==0 ){ return CONFIGSET_ALIAS; } return 0; } /* ** A mask of all configuration tables that have been reset already. */ static int configHasBeenReset = 0; /* ** Mask of modified configuration sets */ static int rebuildMask = 0; /* ................................................................................ ** /concealed $MTIME $HASH content $VALUE ** ** OLD FORMAT: ** ** The old format is retained for backwards compatibility, but is deprecated. ** The cutover from old format to new was on 2011-04-25. After sufficient ** time has passed, support for the old format will be removed. ** Update: Support for the old format was remoed on 2017-09-20. ** ** zName is either the NAME of an element of the CONFIG table, or else ** one of the special names "@shun", "@reportfmt", "@user", or "@concealed". ** If zName is a CONFIG table name, then CONTENT replaces (overwrites) the ** element in the CONFIG table. For one of the @-labels, CONTENT is raw ** SQL that is evaluated. Note that the raw SQL in CONTENT might not ** insert directly into the target table but might instead use a proxy ................................................................................ blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s", aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/, azToken[0]/*safe-for-%s*/); db_multi_exec("%s", blob_sql_text(&sql)); } blob_reset(&sql); rebuildMask |= thisMask; } } /* ** Process a file full of "config" cards. */ void configure_receive_all(Blob *pIn, int groupMask){ ................................................................................ ); blob_appendf(pOut, "config /concealed %d\n%s\n", blob_size(&rec), blob_str(&rec)); nCard++; blob_reset(&rec); } db_finalize(&q); } if( groupMask & CONFIGSET_ALIAS ){ db_prepare(&q, "SELECT mtime, quote(name), quote(value) FROM config" " WHERE name GLOB 'walias:/*' AND mtime>=%lld", iStart); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(&rec,"%s %s value %s", db_column_text(&q, 0), db_column_text(&q, 1), db_column_text(&q, 2) ); blob_appendf(pOut, "config /config %d\n%s\n", blob_size(&rec), blob_str(&rec)); nCard++; blob_reset(&rec); } db_finalize(&q); } db_prepare(&q, "SELECT mtime, quote(name), quote(value) FROM config" " WHERE name=:name AND mtime>=%lld", iStart); for(ii=0; ii<count(aConfig); ii++){ if( (aConfig[ii].groupMask & groupMask)!=0 && aConfig[ii].zName[0]!='@' ){ db_bind_text(&q, ":name", aConfig[ii].zName); while( db_step(&q)==SQLITE_ROW ){ ................................................................................ ** ** Where METHOD is one of: export import merge pull push reset. All methods ** accept the -R or --repository option to specify a repository. ** ** %fossil configuration export AREA FILENAME ** ** Write to FILENAME exported configuration information for AREA. ** AREA can be one of: all email project shun skin ticket user alias ** ** %fossil configuration import FILENAME ** ** Read a configuration from FILENAME, overwriting the current ** configuration. ** ** %fossil configuration merge FILENAME ................................................................................ ** the current configuration. Existing values take priority over ** values read from FILENAME. ** ** %fossil configuration pull AREA ?URL? ** ** Pull and install the configuration from a different server ** identified by URL. If no URL is specified, then the default ** server is used. Use the --overwrite flag to completely ** replace local settings with content received from URL. ** ** %fossil configuration push AREA ?URL? ** ** Push the local configuration into the remote server identified ** by URL. Admin privilege is required on the remote server for ** this to work. When the same record exists both locally and on ** the remote end, the one that was most recently changed wins. ** ** %fossil configuration reset AREA ** ** Restore the configuration to the default. AREA as above. ** ** %fossil configuration sync AREA ?URL? ** ................................................................................ }else if( strncmp(zMethod, "pull", n)==0 || strncmp(zMethod, "push", n)==0 || strncmp(zMethod, "sync", n)==0 ){ int mask; const char *zServer = 0; int overwriteFlag = 0; if( strncmp(zMethod,"pull",n)==0 ){ overwriteFlag = find_option("overwrite",0,0)!=0; } url_proxy_options(); if( g.argc!=4 && g.argc!=5 ){ usage(mprintf("%s AREA ?URL?", zMethod)); } ................................................................................ if( g.argc==5 ){ zServer = g.argv[4]; } url_parse(zServer, URL_PROMPT_PW); if( g.url.protocol==0 ) fossil_fatal("no server URL specified"); user_select(); url_enable_proxy("via proxy: "); if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; if( strncmp(zMethod, "push", n)==0 ){ client_sync(0,0,(unsigned)mask); }else if( strncmp(zMethod, "pull", n)==0 ){ client_sync(0,(unsigned)mask,0); }else{ client_sync(0,(unsigned)mask,(unsigned)mask); |
Changes to src/content.c.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 ... 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 ... 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 ... 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 ... 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 ... 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 |
contentCache.szTotal = 0; } /* ** Return the srcid associated with rid. Or return 0 if rid is ** original content and not a delta. */ static int findSrcid(int rid){ static Stmt q; int srcid; db_static_prepare(&q, "SELECT srcid FROM delta WHERE rid=:rid"); db_bind_int(&q, ":rid", rid); if( db_step(&q)==SQLITE_ROW ){ srcid = db_column_int(&q, 0); }else{ ................................................................................ if( bag_find(&contentCache.available, rid) ){ return 1; } if( content_size(rid, -1)<0 ){ bag_insert(&contentCache.missing, rid); return 0; } srcid = findSrcid(rid); if( srcid==0 ){ bag_insert(&contentCache.available, rid); return 1; } rid = srcid; } fossil_panic("delta-loop in repository"); ................................................................................ blob_copy(pBlob, &contentCache.a[i].content); contentCache.a[i].age = contentCache.nextAge++; return 1; } } } nextRid = findSrcid(rid); if( nextRid==0 ){ rc = content_of_blob(rid, pBlob); }else{ int n = 1; int nAlloc = 10; int *a = 0; int mx; ................................................................................ Blob delta, next; a = fossil_malloc( sizeof(a[0])*nAlloc ); a[0] = rid; a[1] = nextRid; n = 1; while( !bag_find(&contentCache.inCache, nextRid) && (nextRid = findSrcid(nextRid))>0 ){ n++; if( n>=nAlloc ){ if( n>db_int(0, "SELECT max(rid) FROM blob") ){ fossil_panic("infinite loop in DELTA table"); } nAlloc = nAlloc*2 + 10; a = fossil_realloc(a, nAlloc*sizeof(a[0])); ................................................................................ } /* ** Make sure the content at rid is the original content and is not a ** delta. */ void content_undelta(int rid){ if( findSrcid(rid)>0 ){ Blob x; if( content_get(rid, &x) ){ Stmt s; db_prepare(&s, "UPDATE blob SET content=:c, size=%d WHERE rid=%d", blob_size(&x), rid); blob_compress(&x, &x); db_bind_blob(&s, ":c", &x); ................................................................................ "DELETE FROM private WHERE rid=:rid" ); db_bind_int(&s1, ":rid", rid); db_exec(&s1); } /* ** Change the storage of rid so that it is a delta of srcid. ** ** If rid is already a delta from some other place then no ** conversion occurs and this is a no-op unless force==1. ** ** Never generate a delta that carries a private artifact into a public ** artifact. Otherwise, when we go to send the public artifact on a ** sync operation, the other end of the sync will never be able to receive ** the source of the delta. It is OK to delta private->private and ** public->private and public->public. Just no private->public delta. ** ** If srcid is a delta that depends on rid, then srcid is ** converted to undeltaed text. ** ** If either rid or srcid contain less than 50 bytes, or if the ** resulting delta does not achieve a compression of at least 25% ** the rid is left untouched. ** ** Return 1 if a delta is made and 0 if no delta occurs. */ int content_deltify(int rid, int srcid, int force){ int s; Blob data, src, delta; Stmt s1, s2; int rc = 0; if( srcid==rid ) return 0; if( !force && findSrcid(rid)>0 ) return 0; if( content_is_private(srcid) && !content_is_private(rid) ){ return 0; } s = srcid; while( (s = findSrcid(s))>0 ){ if( s==rid ){ content_undelta(srcid); break; } } content_get(srcid, &src); if( blob_size(&src)<50 ){ blob_reset(&src); return 0; } content_get(rid, &data); if( blob_size(&data)<50 ){ blob_reset(&src); blob_reset(&data); return 0; } blob_delta_create(&src, &data, &delta); if( blob_size(&delta) <= blob_size(&data)*0.75 ){ blob_compress(&delta, &delta); db_prepare(&s1, "UPDATE blob SET content=:data WHERE rid=%d", rid); db_prepare(&s2, "REPLACE INTO delta(rid,srcid)VALUES(%d,%d)", rid, srcid); db_bind_blob(&s1, ":data", &delta); db_begin_transaction(); db_exec(&s1); db_exec(&s2); db_end_transaction(0); db_finalize(&s1); db_finalize(&s2); verify_before_commit(rid); rc = 1; } blob_reset(&src); blob_reset(&data); blob_reset(&delta); return rc; } /* ** COMMAND: test-content-deltify ** ** Convert the content at RID into a delta from SRCID. */ void test_content_deltify_cmd(void){ if( g.argc!=5 ) usage("RID SRCID FORCE"); db_must_be_within_tree(); content_deltify(atoi(g.argv[2]), atoi(g.argv[3]), atoi(g.argv[4])); } /* ** Return true if Blob p looks like it might be a parsable control artifact. */ static int looks_like_control_artifact(Blob *p){ const char *z = blob_buffer(p); |
| | | | | | > > | > | | > | | | | > > > | > > > > > > > > > > > > > > > > > > > > > | < | < | > > > | | | | | | | > > | | > | < > | < > | > > > > > > > > | > | < < < > > > > > | | | < | > > | < > > > > > > > > | |
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 ... 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 ... 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 ... 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 ... 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 ... 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 |
contentCache.szTotal = 0; } /* ** Return the srcid associated with rid. Or return 0 if rid is ** original content and not a delta. */ int delta_source_rid(int rid){ static Stmt q; int srcid; db_static_prepare(&q, "SELECT srcid FROM delta WHERE rid=:rid"); db_bind_int(&q, ":rid", rid); if( db_step(&q)==SQLITE_ROW ){ srcid = db_column_int(&q, 0); }else{ ................................................................................ if( bag_find(&contentCache.available, rid) ){ return 1; } if( content_size(rid, -1)<0 ){ bag_insert(&contentCache.missing, rid); return 0; } srcid = delta_source_rid(rid); if( srcid==0 ){ bag_insert(&contentCache.available, rid); return 1; } rid = srcid; } fossil_panic("delta-loop in repository"); ................................................................................ blob_copy(pBlob, &contentCache.a[i].content); contentCache.a[i].age = contentCache.nextAge++; return 1; } } } nextRid = delta_source_rid(rid); if( nextRid==0 ){ rc = content_of_blob(rid, pBlob); }else{ int n = 1; int nAlloc = 10; int *a = 0; int mx; ................................................................................ Blob delta, next; a = fossil_malloc( sizeof(a[0])*nAlloc ); a[0] = rid; a[1] = nextRid; n = 1; while( !bag_find(&contentCache.inCache, nextRid) && (nextRid = delta_source_rid(nextRid))>0 ){ n++; if( n>=nAlloc ){ if( n>db_int(0, "SELECT max(rid) FROM blob") ){ fossil_panic("infinite loop in DELTA table"); } nAlloc = nAlloc*2 + 10; a = fossil_realloc(a, nAlloc*sizeof(a[0])); ................................................................................ } /* ** Make sure the content at rid is the original content and is not a ** delta. */ void content_undelta(int rid){ if( delta_source_rid(rid)>0 ){ Blob x; if( content_get(rid, &x) ){ Stmt s; db_prepare(&s, "UPDATE blob SET content=:c, size=%d WHERE rid=%d", blob_size(&x), rid); blob_compress(&x, &x); db_bind_blob(&s, ":c", &x); ................................................................................ "DELETE FROM private WHERE rid=:rid" ); db_bind_int(&s1, ":rid", rid); db_exec(&s1); } /* ** Try to change the storage of rid so that it is a delta from one ** of the artifacts given in aSrc[0]..aSrc[nSrc-1]. The aSrc[*] that ** gives the smallest delta is choosen. ** ** If rid is already a delta from some other place then no ** conversion occurs and this is a no-op unless force==1. If force==1, ** then nSrc must also be 1. ** ** Never generate a delta that carries a private artifact into a public ** artifact. Otherwise, when we go to send the public artifact on a ** sync operation, the other end of the sync will never be able to receive ** the source of the delta. It is OK to delta private->private and ** public->private and public->public. Just no private->public delta. ** ** If aSrc[bestSrc] is already a dleta that depends on rid, then it is ** converted to undeltaed text before the aSrc[bestSrc]->rid delta is ** created, in order to prevent a delta loop. ** ** If either rid or aSrc[i] contain less than 50 bytes, or if the ** resulting delta does not achieve a compression of at least 25% ** the rid is left untouched. ** ** Return 1 if a delta is made and 0 if no delta occurs. */ int content_deltify(int rid, int *aSrc, int nSrc, int force){ int s; Blob data; /* Content of rid */ Blob src; /* Content of aSrc[i] */ Blob delta; /* Delta from aSrc[i] to rid */ Blob bestDelta; /* Best delta seen so far */ int bestSrc = 0; /* Which aSrc is the source of the best delta */ int rc = 0; /* Value to return */ int i; /* Loop variable for aSrc[] */ /* If rid is already a child (a delta) of some other artifact, return ** immediately if the force flags is false */ if( !force && delta_source_rid(rid)>0 ) return 0; /* Get the complete content of the object to be delta-ed. If the size ** is less than 50 bytes, then there really is no point in trying to do ** a delta, so return immediately */ content_get(rid, &data); if( blob_size(&data)<50 ){ /* Do not try to create a delta for objects smaller than 50 bytes */ blob_reset(&data); return 0; } blob_init(&bestDelta, 0, 0); /* Loop over all candidate delta sources */ for(i=0; i<nSrc; i++){ int srcid = aSrc[i]; if( srcid==rid ) continue; if( content_is_private(srcid) && !content_is_private(rid) ) continue; /* Compute all ancestors of srcid and make sure rid is not one of them. ** If rid is an ancestor of srcid, then making rid a decendent of srcid ** would create a delta loop. */ s = srcid; while( (s = delta_source_rid(s))>0 ){ if( s==rid ){ content_undelta(srcid); break; } } if( s!=0 ) continue; content_get(srcid, &src); if( blob_size(&src)<50 ){ /* The source is smaller then 50 bytes, so don't bother trying to use it*/ blob_reset(&src); continue; } blob_delta_create(&src, &data, &delta); if( blob_size(&delta) < blob_size(&data)*0.75 && (bestSrc<=0 || blob_size(&delta)<blob_size(&bestDelta)) ){ /* This is the best delta seen so far. Remember it */ blob_reset(&bestDelta); bestDelta = delta; bestSrc = srcid; }else{ /* This delta is not a candidate for becoming the new parent of rid */ blob_reset(&delta); } blob_reset(&src); } /* If there is a winning candidate for the new parent of rid, then ** make that candidate the new parent now */ if( bestSrc>0 ){ Stmt s1, s2; /* Statements used to create the delta */ blob_compress(&bestDelta, &bestDelta); db_prepare(&s1, "UPDATE blob SET content=:data WHERE rid=%d", rid); db_prepare(&s2, "REPLACE INTO delta(rid,srcid)VALUES(%d,%d)", rid, bestSrc); db_bind_blob(&s1, ":data", &bestDelta); db_begin_transaction(); db_exec(&s1); db_exec(&s2); db_end_transaction(0); db_finalize(&s1); db_finalize(&s2); verify_before_commit(rid); rc = 1; } blob_reset(&data); blob_reset(&bestDelta); return rc; } /* ** COMMAND: test-content-deltify ** ** Usage: %fossil RID SRCID SRCID ... [-force] ** ** Convert the content at RID into a delta one of the from SRCIDs. */ void test_content_deltify_cmd(void){ int nSrc; int *aSrc; int i; int bForce = find_option("force",0,0)!=0; if( g.argc<3 ) usage("[--force] RID SRCID SRCID..."); aSrc = fossil_malloc( (g.argc-2)*sizeof(aSrc[0]) ); nSrc = 0; for(i=2; i<g.argc; i++) aSrc[nSrc++] = atoi(g.argv[i]); db_must_be_within_tree(); content_deltify(atoi(g.argv[2]), aSrc, nSrc, bForce); } /* ** Return true if Blob p looks like it might be a parsable control artifact. */ static int looks_like_control_artifact(Blob *p){ const char *z = blob_buffer(p); |
Changes to src/db.c.
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 .... 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 .... 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 .... 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 .... 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 .... 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 .... 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 |
return 1; #endif } /* ** Returns non-zero if support for symlinks is currently enabled. */ int db_allow_symlinks(int traversal){ if( traversal ){ if( g.allowSymlinks ) return 1; return g.fNoDirSymlinks; }else{ return g.allowSymlinks; } } /* ** Open the repository database given by zDbName. If zDbName==NULL then ** get the name from the already open local database. */ void db_open_repository(const char *zDbName){ ................................................................................ ** Return a pointer to a string that contains the RHS of an IN operator ** that will select CONFIG table names that are in the list of control ** settings. */ const char *db_setting_inop_rhs(){ Blob x; int i; const char *zSep = ""; blob_zero(&x); blob_append_sql(&x, "("); for(i=0; aSetting[i].name; i++){ blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, aSetting[i].name); zSep = ","; } blob_append_sql(&x, ")"); return blob_sql_text(&x); } ................................................................................ char *zDate; Blob hash; Blob manifest; db_set("content-schema", CONTENT_SCHEMA, 0); db_set("aux-schema", AUX_SCHEMA_MAX, 0); db_set("rebuilt", get_version(), 0); db_multi_exec( "INSERT INTO config(name,value,mtime)" " VALUES('server-code', lower(hex(randomblob(20))),now());" "INSERT INTO config(name,value,mtime)" " VALUES('project-code', lower(hex(randomblob(20))),now());" ); if( !db_is_global("autosync") ) db_set_int("autosync", 1, 0); ................................................................................ if( zTemplate ){ /* ** Copy all settings from the supplied template repository. */ db_multi_exec( "INSERT OR REPLACE INTO config" " SELECT name,value,mtime FROM settingSrc.config" " WHERE (name IN %s OR name IN %s)" " AND name NOT GLOB 'project-*'" " AND name NOT GLOB 'short-project-*';", configure_inop_rhs(CONFIGSET_ALL), db_setting_inop_rhs() ); g.eHashPolicy = db_get_int("hash-policy", g.eHashPolicy); db_multi_exec( ................................................................................ fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", pSetting->name); } } db_finalize(&q); } #if INTERFACE /* ** Define all settings, which can be controlled via the set/unset ** command. ** ** var is the name of the internal configuration name for db_(un)set. ** If var is 0, the settings name is used. ................................................................................ int width; /* Width of display. 0 for boolean values. */ int versionable; /* Is this setting versionable? */ int forceTextArea; /* Force using a text area for display? */ const char *def; /* Default value */ }; #endif /* INTERFACE */ const Setting aSetting[] = { { "access-log", 0, 0, 0, 0, "off" }, { "admin-log", 0, 0, 0, 0, "off" }, #if defined(_WIN32) { "allow-symlinks", 0, 0, 1, 0, "off" }, #else { "allow-symlinks", 0, 0, 1, 0, "on" }, #endif { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, { "auto-hyperlink", 0, 0, 0, 0, "on", }, { "auto-shun", 0, 0, 0, 0, "on" }, { "autosync", 0, 0, 0, 0, "on" }, { "autosync-tries", 0, 16, 0, 0, "1" }, { "binary-glob", 0, 40, 1, 0, "" }, #if defined(_WIN32) || defined(__CYGWIN__) || defined(__DARWIN__) || \ defined(__APPLE__) { "case-sensitive", 0, 0, 0, 0, "off" }, #else { "case-sensitive", 0, 0, 0, 0, "on" }, #endif { "clean-glob", 0, 40, 1, 0, "" }, { "clearsign", 0, 0, 0, 0, "off" }, { "crlf-glob", 0, 40, 1, 0, "" }, { "crnl-glob", 0, 40, 1, 0, "" }, { "default-perms", 0, 16, 0, 0, "u" }, { "diff-binary", 0, 0, 0, 0, "on" }, { "diff-command", 0, 40, 0, 0, "" }, { "dont-push", 0, 0, 0, 0, "off" }, { "dotfiles", 0, 0, 1, 0, "off" }, { "editor", 0, 32, 0, 0, "" }, { "empty-dirs", 0, 40, 1, 0, "" }, { "encoding-glob", 0, 40, 1, 0, "" }, #if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) { "exec-rel-paths", 0, 0, 0, 0, "on" }, #else { "exec-rel-paths", 0, 0, 0, 0, "off" }, #endif { "gdiff-command", 0, 40, 0, 0, "gdiff" }, { "gmerge-command", 0, 40, 0, 0, "" }, { "hash-digits", 0, 5, 0, 0, "10" }, { "http-port", 0, 16, 0, 0, "8080" }, { "https-login", 0, 0, 0, 0, "off" }, { "ignore-glob", 0, 40, 1, 0, "" }, { "keep-glob", 0, 40, 1, 0, "" }, { "localauth", 0, 0, 0, 0, "off" }, { "main-branch", 0, 40, 0, 0, "trunk" }, { "manifest", 0, 5, 1, 0, "" }, { "max-loadavg", 0, 25, 0, 0, "0.0" }, { "max-upload", 0, 25, 0, 0, "250000" }, { "mtime-changes", 0, 0, 0, 0, "on" }, #if FOSSIL_ENABLE_LEGACY_MV_RM { "mv-rm-files", 0, 0, 0, 0, "off" }, #endif { "pgp-command", 0, 40, 0, 0, "gpg --clearsign -o " }, { "proxy", 0, 32, 0, 0, "off" }, { "relative-paths", 0, 0, 0, 0, "on" }, { "repo-cksum", 0, 0, 0, 0, "on" }, { "self-register", 0, 0, 0, 0, "off" }, { "ssh-command", 0, 40, 0, 0, "" }, { "ssl-ca-location", 0, 40, 0, 0, "" }, { "ssl-identity", 0, 40, 0, 0, "" }, #ifdef FOSSIL_ENABLE_TCL { "tcl", 0, 0, 0, 0, "off" }, { "tcl-setup", 0, 40, 1, 1, "" }, #endif #ifdef FOSSIL_ENABLE_TH1_DOCS { "th1-docs", 0, 0, 0, 0, "off" }, #endif #ifdef FOSSIL_ENABLE_TH1_HOOKS { "th1-hooks", 0, 0, 0, 0, "off" }, #endif { "th1-setup", 0, 40, 1, 1, "" }, { "th1-uri-regexp", 0, 40, 1, 0, "" }, { "uv-sync", 0, 0, 0, 0, "off" }, { "web-browser", 0, 32, 0, 0, "" }, { 0,0,0,0,0,0 } }; /* ** Look up a control setting by its name. Return a pointer to the Setting ** object, or NULL if there is no such setting. ** ** If allowPrefix is true, then the Setting returned is the first one for ** which zName is a prefix of the Setting name. */ const Setting *db_find_setting(const char *zName, int allowPrefix){ int lwr, mid, upr, c; int n = (int)strlen(zName) + !allowPrefix; lwr = 0; upr = count(aSetting)-2; while( upr>=lwr ){ mid = (upr+lwr)/2; c = fossil_strncmp(zName, aSetting[mid].name, n); if( c<0 ){ upr = mid - 1; }else if( c>0 ){ lwr = mid + 1; }else{ if( allowPrefix ){ while( mid>lwr && fossil_strncmp(zName, aSetting[mid-1].name, n)==0 ){ mid--; } } return &aSetting[mid]; } } return 0; } /* ** COMMAND: settings ** COMMAND: unset* ** ** Usage: %fossil settings ?PROPERTY? ?VALUE? ?OPTIONS? ** or: %fossil unset PROPERTY ?OPTIONS? ** ** The "settings" command with no arguments lists all properties and their ** values. With just a property name it shows the value of that property. ** With a value argument it changes the property for the current repository. ** ** Settings marked as versionable are overridden by the contents of the ** file named .fossil-settings/PROPERTY in the check-out root, if that ** file exists. ** ** The "unset" command clears a property setting. ** ** ** access-log If enabled, record successful and failed login attempts ** in the "accesslog" table. Default: off ** ** admin-log If enabled, record configuration changes in the ** "admin_log" table. Default: off ** ** allow-symlinks If enabled, don't follow symlinks, and instead treat ** (versionable) them as symlinks on Unix. Has no effect on Windows ** (existing links in repository created on Unix become ** plain-text files with link destination path inside). ** Default: on (Unix), off (Windows) ** ** 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" ** then only pull operations occur automatically. ** Default: on ** ** autosync-tries If autosync is enabled setting this to a value greater ** than zero will cause autosync to try no more than this ** number of attempts if there is a sync failure. ** Default: 1 ** ** binary-glob The VALUE is a comma or newline-separated list of ** (versionable) GLOB patterns that should be treated as binary files ** for committing and merging purposes. Example: *.jpg ** ** case-sensitive If TRUE, the files whose names differ only in case ** are considered distinct. If FALSE files whose names ** differ only in case are the same file. Defaults to ** TRUE for unix and FALSE for Cygwin, Mac and Windows. ** ** clean-glob The VALUE is a comma or newline-separated list of GLOB ** (versionable) patterns specifying files that the "clean" command will ** delete without prompting or allowing undo. ** Example: *.a,*.lib,*.o ** ** clearsign When enabled, fossil will attempt to sign all commits ** with gpg. When disabled (the default), commits will ** be unsigned. Default: off ** ** crlf-glob A comma or newline-separated list of GLOB patterns for ** (versionable) text files in which it is ok to have CR, CR+LF or mixed ** line endings. Set to "*" to disable CR+LF checking. ** The crnl-glob setting is a compatibility alias. ** ** default-perms Permissions given automatically to new users. For more ** information on permissions see Users page in Server ** Administration of the HTTP UI. Default: u. ** ** diff-binary If TRUE (the default), permit files that may be binary ** or that match the "binary-glob" setting to be used with ** external diff programs. If FALSE, skip these files. ** ** diff-command External command to run when performing a diff. ** If undefined, the internal text diff will be used. ** ** dont-push Prevent this repository from pushing from client to ** server. Useful when setting up a private branch. ** ** dotfiles Include --dotfiles option for all compatible commands. ** (versionable) ** ** editor Text editor command used for check-in comments. ** ** empty-dirs A comma or newline-separated list of pathnames. On ** (versionable) update and checkout commands, if no file or directory ** exists with that name, an empty directory will be ** created. ** ** encoding-glob The VALUE is a comma or newline-separated list of GLOB ** (versionable) patterns specifying files that the "commit" command will ** ignore when issuing warnings about text files that may ** use another encoding than ASCII or UTF-8. Set to "*" ** to disable encoding checking. ** ** exec-rel-paths When executing certain external commands (e.g. diff and ** gdiff), use relative paths. ** ** gdiff-command External command to run when performing a graphical ** diff. If undefined, text diff will be used. ** ** gmerge-command A graphical merge conflict resolver command operating ** on four files. ** Ex: kdiff3 "%baseline" "%original" "%merge" -o "%output" ** Ex: xxdiff "%original" "%baseline" "%merge" -M "%output" ** Ex: meld "%baseline" "%original" "%merge" "%output" ** ** hash-digits The number of hexadecimal digits of the SHA1 hash to ** display. (Default: 10; Minimum: 6) ** ** http-port The TCP/IP port number to use by the "server" ** and "ui" commands. Default: 8080 ** ** https-login Send login credentials using HTTPS instead of HTTP ** even if the login page request came via HTTP. ** ** ignore-glob The VALUE is a comma or newline-separated list of GLOB ** (versionable) patterns specifying files that the "add", "addremove", ** "clean", and "extra" commands will ignore. ** Example: *.log customCode.c notes.txt ** ** keep-glob The VALUE is a comma or newline-separated list of GLOB ** (versionable) patterns specifying files that the "clean" command will ** keep. ** ** localauth If enabled, require that HTTP connections from ** 127.0.0.1 be authenticated by password. If ** false, all HTTP requests from localhost have ** unrestricted access to the repository. ** ** main-branch The primary branch for the project. Default: trunk ** ** manifest If set to a true boolean value, automatically create ** (versionable) files "manifest" and "manifest.uuid" in every checkout. ** Optionally use combinations of characters 'r' ** for "manifest", 'u' for "manifest.uuid" and 't' for ** "manifest.tags". The SQLite and Fossil repositories ** both require manifests. Default: off. ** ** max-loadavg Some CPU-intensive web pages (ex: /zip, /tarball, /blame) ** are disallowed if the system load average goes above this ** value. "0.0" means no limit. This only works on unix. ** Only local settings of this value make a difference since ** when running as a web-server, Fossil does not open the ** global configuration database. ** ** max-upload A limit on the size of uplink HTTP requests. The ** default is 250000 bytes. ** ** mtime-changes Use file modification times (mtimes) to detect when ** files have been modified. (Default "on".) ** ** mv-rm-files If enabled (and Fossil was compiled with legacy "mv/rm" ** support), the "mv" and "rename" commands will also move ** the associated files within the checkout -AND- the "rm" ** and "delete" commands will also remove the associated ** files from within the checkout. Default: off. ** ** pgp-command Command used to clear-sign manifests at check-in. ** The default is "gpg --clearsign -o ". ** ** proxy URL of the HTTP proxy. If undefined or "off" then ** the "http_proxy" environment variable is consulted. ** If the http_proxy environment variable is undefined ** then a direct HTTP connection is used. ** ** relative-paths When showing changes and extras, report paths relative ** to the current working directory. Default: "on" ** ** repo-cksum Compute checksums over all files in each checkout ** as a double-check of correctness. Defaults to "on". ** Disable on large repositories for a performance ** improvement. ** ** self-register Allow users to register themselves through the HTTP UI. ** This is useful if you want to see other names than ** "Anonymous" in e.g. ticketing system. On the other hand ** users can not be deleted. Default: off. ** ** ssh-command Command used to talk to a remote machine with ** the "ssh://" protocol. ** ** ssl-ca-location The full pathname to a file containing PEM encoded ** CA root certificates, or a directory of certificates ** with filenames formed from the certificate hashes as ** required by OpenSSL. ** If set, this will override the OS default list of ** OpenSSL CAs. If unset, the default list will be used. ** Some platforms may add additional certificates. ** Checking your platform behaviour is required if the ** exact contents of the CA root is critical for your ** application. ** ** ssl-identity The full pathname to a file containing a certificate ** and private key in PEM format. Create by concatenating ** the certificate and private key files. ** This identity will be presented to SSL servers to ** authenticate this client, in addition to the normal ** password authentication. ** ** tcl If enabled (and Fossil was compiled with Tcl support), ** Tcl integration commands will be added to the TH1 ** interpreter, allowing arbitrary Tcl expressions and ** scripts to be evaluated from TH1. Additionally, the Tcl ** interpreter will be able to evaluate arbitrary TH1 ** expressions and scripts. Default: off. ** ** tcl-setup This is the setup script to be evaluated after creating ** (versionable) and initializing the Tcl interpreter. By default, this ** is empty and no extra setup is performed. ** ** th1-docs WARNING: If enabled (and Fossil was compiled with TH1 ** support for embedded documentation files), this allows ** embedded documentation files to contain arbitrary TH1 ** scripts that are evaluated on the server. If native ** Tcl integration is also enabled, this setting has the ** potential to allow anybody with check-in privileges to ** do almost anything that the associated operating system ** user account could do. Extreme caution should be used ** when enabling this setting. Default: off. ** ** th1-hooks If enabled (and Fossil was compiled with support for TH1 ** hooks), special TH1 commands will be called before and ** after any Fossil command or web page. Default: off. ** ** th1-setup This is the setup script to be evaluated after creating ** (versionable) and initializing the TH1 interpreter. By default, this ** is empty and no extra setup is performed. ** ** th1-uri-regexp Specify which URI's are allowed in HTTP requests from ** (versionable) TH1 scripts. If empty, no HTTP requests are allowed ** whatsoever. The default is an empty string. ** ** uv-sync If true, automatically send unversioned files as part ** of a "fossil clone" or "fossil sync" command. The ** default is false, in which case the -u option is ** needed to clone or sync unversioned files. ** ** web-browser A shell command used to launch your preferred ** web browser when given a URL as an argument. ** Defaults to "start" on windows, "open" on Mac, ** and "firefox" on Unix. ** ** Options: ** --global set or unset the given property globally instead of ** setting or unsetting it for the open repository only. ** ** --exact only consider exact name matches. ** ................................................................................ ** See also: configuration */ void setting_cmd(void){ int i; int globalFlag = find_option("global","g",0)!=0; int exactFlag = find_option("exact",0,0)!=0; int unsetFlag = g.argv[1][0]=='u'; find_repository_option(); verify_all_options(); db_open_config(1, 0); if( !globalFlag ){ db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0); } if( !g.repositoryOpen ){ globalFlag = 1; } if( unsetFlag && g.argc!=3 ){ usage("PROPERTY ?-global?"); } /* Verify that the aSetting[] entries are in sorted order. This is ** necessary for the binary search in db_find_setting() to work correctly. */ for(i=1; aSetting[i].name; i++){ if( fossil_strcmp(aSetting[i-1].name, aSetting[i].name)>=0 ){ fossil_panic("Internal Error: aSetting[] entries for \"%s\"" " and \"%s\" are out of order.", aSetting[i-1].name, aSetting[i].name); } } if( g.argc==2 ){ for(i=0; aSetting[i].name; i++){ print_setting(&aSetting[i]); } }else if( g.argc==3 || g.argc==4 ){ const char *zName = g.argv[2]; int n = (int)strlen(zName); const Setting *pSetting = db_find_setting(zName, !exactFlag); if( pSetting==0 ){ |
| < < < < | < > > | > > | < < > | < > > > > > > > > > > > < < < > > > > < < < < < < < | < > > > > | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > > > > | < > > > > > > < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > > > > > > < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < > > > > > > > > > > > > > > > < > > > > > > > > > > < > > > > > < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > | > > < > | | | | | | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > < < < < < < < < < < < < > |
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 .... 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 .... 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 .... 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 .... 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 .... 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 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 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 .... 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 |
return 1; #endif } /* ** Returns non-zero if support for symlinks is currently enabled. */ int db_allow_symlinks(void){ return g.allowSymlinks; } /* ** Open the repository database given by zDbName. If zDbName==NULL then ** get the name from the already open local database. */ void db_open_repository(const char *zDbName){ ................................................................................ ** Return a pointer to a string that contains the RHS of an IN operator ** that will select CONFIG table names that are in the list of control ** settings. */ const char *db_setting_inop_rhs(){ Blob x; int i; int nSetting; const Setting *aSetting = setting_info(&nSetting); const char *zSep = ""; blob_zero(&x); blob_append_sql(&x, "("); for(i=0; i<nSetting; i++){ blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, aSetting[i].name); zSep = ","; } blob_append_sql(&x, ")"); return blob_sql_text(&x); } ................................................................................ char *zDate; Blob hash; Blob manifest; db_set("content-schema", CONTENT_SCHEMA, 0); db_set("aux-schema", AUX_SCHEMA_MAX, 0); db_set("rebuilt", get_version(), 0); db_set("admin-log", "1", 0); db_set("access-log", "1", 0); db_multi_exec( "INSERT INTO config(name,value,mtime)" " VALUES('server-code', lower(hex(randomblob(20))),now());" "INSERT INTO config(name,value,mtime)" " VALUES('project-code', lower(hex(randomblob(20))),now());" ); if( !db_is_global("autosync") ) db_set_int("autosync", 1, 0); ................................................................................ if( zTemplate ){ /* ** Copy all settings from the supplied template repository. */ db_multi_exec( "INSERT OR REPLACE INTO config" " SELECT name,value,mtime FROM settingSrc.config" " WHERE (name IN %s OR name IN %s OR name GLOB 'walias:/*')" " AND name NOT GLOB 'project-*'" " AND name NOT GLOB 'short-project-*';", configure_inop_rhs(CONFIGSET_ALL), db_setting_inop_rhs() ); g.eHashPolicy = db_get_int("hash-policy", g.eHashPolicy); db_multi_exec( ................................................................................ fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", pSetting->name); } } db_finalize(&q); } #if INTERFACE /* ** Define all settings, which can be controlled via the set/unset ** command. ** ** var is the name of the internal configuration name for db_(un)set. ** If var is 0, the settings name is used. ................................................................................ int width; /* Width of display. 0 for boolean values. */ int versionable; /* Is this setting versionable? */ int forceTextArea; /* Force using a text area for display? */ const char *def; /* Default value */ }; #endif /* INTERFACE */ /* ** SETTING: access-log boolean default=off ** ** When the access-log setting is enabled, all login attempts (successful ** and unsuccessful) on the web interface are recorded in the "access" table ** of the repository. */ /* ** SETTING: admin-log boolean default=off ** ** When the admin-log setting is enabled, configuration changes are recorded ** in the "admin_log" table of the repository. */ #if defined(_WIN32) /* ** SETTING: allow-symlinks boolean default=off versionable ** Allows symbolic links in the repository when enabled. */ #endif #if !defined(_WIN32) /* ** SETTING: allow-symlinks boolean default=on versionable ** Allows symbolic links in the repository when enabled. */ #endif /* ** SETTING: auto-captcha boolean default=on variable=autocaptcha ** If enabled, the /login page provides a button that will automatically ** fill in the captcha password. This makes things easier for human users, ** at the expense of also making logins easier for malecious robots. */ /* ** SETTING: auto-hyperlink boolean default=on ** 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. */ /* ** SETTING: auto-shun boolean default=on ** If enabled, automatically pull the shunning list ** from a server to which the client autosyncs. */ /* ** SETTING: autosync width=16 default=on ** This setting can take either a boolean value or "pullonly" ** If enabled, automatically pull prior to commit ** or update and automatically push after commit or ** tag or branch creation. If the value is "pullonly" ** then only pull operations occur automatically. */ /* ** SETTING: autosync-tries width=16 default=1 ** If autosync is enabled setting this to a value greater ** than zero will cause autosync to try no more than this ** number of attempts if there is a sync failure. */ /* ** SETTING: binary-glob width=40 versionable block-text ** The VALUE of this setting is a comma or newline-separated list of ** GLOB patterns that should be treated as binary files ** for committing and merging purposes. Example: *.jpg */ #if defined(_WIN32)||defined(__CYGWIN__)||defined(__DARWIN__) /* ** SETTING: case-sensitive boolean default=off ** If TRUE, the files whose names differ only in case ** are considered distinct. If FALSE files whose names ** differ only in case are the same file. Defaults to ** TRUE for unix and FALSE for Cygwin, Mac and Windows. */ #endif #if !(defined(_WIN32)||defined(__CYGWIN__)||defined(__DARWIN__)) /* ** SETTING: case-sensitive boolean default=on ** If TRUE, the files whose names differ only in case ** are considered distinct. If FALSE files whose names ** differ only in case are the same file. Defaults to ** TRUE for unix and FALSE for Cygwin, Mac and Windows. */ #endif /* ** SETTING: clean-glob width=40 versionable block-text ** The VALUE of this setting is a comma or newline-separated list of GLOB ** patterns specifying files that the "clean" command will ** delete without prompting or allowing undo. ** Example: *.a,*.lib,*.o */ /* ** SETTING: clearsign boolean default=off ** When enabled, fossil will attempt to sign all commits ** with gpg. When disabled, commits will be unsigned. */ /* ** SETTING: crlf-glob width=40 versionable block-text ** The value is a comma or newline-separated list of GLOB patterns for ** text files in which it is ok to have CR, CR+LF or mixed ** line endings. Set to "*" to disable CR+LF checking. ** The crnl-glob setting is a compatibility alias. */ /* ** SETTING: crnl-glob width=40 versionable block-text ** This is an alias for the crlf-glob setting */ /* ** SETTING: default-perms width=16 default=u ** Permissions given automatically to new users. For more ** information on permissions see the Users page in Server ** Administration of the HTTP UI. */ /* ** SETTING: diff-binary boolean default=on ** If enabled, permit files that may be binary ** or that match the "binary-glob" setting to be used with ** external diff programs. If disabled, skip these files. */ /* ** SETTING: diff-command width=40 ** The value is an external command to run when performing a diff. ** If undefined, the internal text diff will be used. */ /* ** SETTING: dont-push boolean default=off ** If enabled, prevent this repository from pushing from client to ** server. This can be used as an extra precaution to prevent ** accidental pushes to a public server from a private clone. */ /* ** SETTING: dotfiles boolean versionable default=off ** If enabled, include --dotfiles option for all compatible commands. */ /* ** SETTING: editor width=32 ** The value is an external command that will launch the ** text editor command used for check-in comments. */ /* ** SETTING: empty-dirs width=40 versionable block-text ** The value is a comma or newline-separated list of pathnames. On ** update and checkout commands, if no file or directory ** exists with that name, an empty directory will be ** created. */ /* ** SETTING: encoding-glob width=40 versionable block-text ** The value is a comma or newline-separated list of GLOB ** patterns specifying files that the "commit" command will ** ignore when issuing warnings about text files that may ** use another encoding than ASCII or UTF-8. Set to "*" ** to disable encoding checking. */ #if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) /* ** SETTING: exec-rel-paths boolean default=on ** When executing certain external commands (e.g. diff and ** gdiff), use relative paths. */ #endif #if !defined(FOSSIL_ENABLE_EXEC_REL_PATHS) /* ** SETTING: exec-rel-paths boolean default=off ** When executing certain external commands (e.g. diff and ** gdiff), use relative paths. */ #endif /* ** SETTING: gdiff-command width=40 default=gdiff ** The value is an external command to run when performing a graphical ** diff. If undefined, text diff will be used. */ /* ** SETTING: gmerge-command width=40 ** The value is a graphical merge conflict resolver command operating ** on four files. Examples: ** ** kdiff3 "%baseline" "%original" "%merge" -o "%output" ** xxdiff "%original" "%baseline" "%merge" -M "%output" ** meld "%baseline" "%original" "%merge" "%output" */ /* ** SETTING: hash-digits width=5 default=10 ** The number of hexadecimal digits of the SHA3 hash to display. */ /* ** SETTING: http-port width=16 default=8080 ** The default TCP/IP port number to use by the "server" ** and "ui" commands. */ /* ** SETTING: https-login boolean default=off ** If true, then the Fossil web server will redirect unencrypted ** login screeen requests to HTTPS. */ /* ** SETTING: ignore-glob width=40 versionable block-text ** The value is a comma or newline-separated list of GLOB ** patterns specifying files that the "add", "addremove", ** "clean", and "extras" commands will ignore. ** ** Example: *.log customCode.c notes.txt */ /* ** SETTING: keep-glob width=40 versionable block-text ** The value is a comma or newline-separated list of GLOB ** patterns specifying files that the "clean" command will keep */ /* ** SETTING: localauth boolean default=off ** If enabled, require that HTTP connections from ** 127.0.0.1 be authenticated by password. If ** false, all HTTP requests from localhost have ** unrestricted access to the repository. */ /* ** SETTING: main-branch width=40 default=trunk ** The value is the primary branch for the project. */ /* ** SETTING: manifest width=5 versionable ** If enabled, automatically create files "manifest" and "manifest.uuid" ** in every checkout. ** ** Optionally use combinations of characters 'r' for "manifest", ** 'u' for "manifest.uuid" and 't' for "manifest.tags". The SQLite ** and Fossil repositories both require manifests. */ /* ** SETTING: max-loadavg width=25 default=0.0 ** Some CPU-intensive web pages (ex: /zip, /tarball, /blame) ** are disallowed if the system load average goes above this ** value. "0.0" means no limit. This only works on unix. ** Only local settings of this value make a difference since ** when running as a web-server, Fossil does not open the ** global configuration database. */ /* ** SETTING: max-upload width=25 default=250000 ** A limit on the size of uplink HTTP requests. */ /* ** SETTING: mtime-changes boolean default=on ** Use file modification times (mtimes) to detect when ** files have been modified. If disabled, all managed files ** are hashed to detect changes, which can be slow for large ** projects. */ #if FOSSIL_ENABLE_LEGACY_MV_RM /* ** SETTING: mv-rm-files boolean default=off ** If enabled, the "mv" and "rename" commands will also move ** the associated files within the checkout -AND- the "rm" ** and "delete" commands will also remove the associated ** files from within the checkout. */ #endif /* ** SETTING: pgp-command width=40 ** Command used to clear-sign manifests at check-in. ** Default value is "gpg --clearsign -o" */ /* ** SETTING: proxy width=32 default=off ** URL of the HTTP proxy. If undefined or "off" then ** the "http_proxy" environment variable is consulted. ** If the http_proxy environment variable is undefined ** then a direct HTTP connection is used. */ /* ** SETTING: relative-paths boolean default=on ** When showing changes and extras, report paths relative ** to the current working directory. */ /* ** SETTING: repo-cksum boolean default=on ** Compute checksums over all files in each checkout as a double-check ** of correctness. Disable this on large repositories for a performance ** improvement. */ /* ** SETTING: self-register boolean default=off ** Allow users to register themselves through the HTTP UI. ** This is useful if you want to see other names than ** "Anonymous" in e.g. ticketing system. On the other hand ** users can not be deleted. */ /* ** SETTING: ssh-command width=40 ** The command used to talk to a remote machine with the "ssh://" protocol. */ /* ** SETTING: ssl-ca-location width=40 ** The full pathname to a file containing PEM encoded ** CA root certificates, or a directory of certificates ** with filenames formed from the certificate hashes as ** required by OpenSSL. ** ** If set, this will override the OS default list of ** OpenSSL CAs. If unset, the default list will be used. ** Some platforms may add additional certificates. ** Checking your platform behaviour is required if the ** exact contents of the CA root is critical for your ** application. */ /* ** SETTING: ssl-identity width=40 ** The full pathname to a file containing a certificate ** and private key in PEM format. Create by concatenating ** the certificate and private key files. ** ** This identity will be presented to SSL servers to ** authenticate this client, in addition to the normal ** password authentication. */ #ifdef FOSSIL_ENABLE_TCL /* ** SETTING: tcl boolean default=off ** If enabled Tcl integration commands will be added to the TH1 ** interpreter, allowing arbitrary Tcl expressions and ** scripts to be evaluated from TH1. Additionally, the Tcl ** interpreter will be able to evaluate arbitrary TH1 ** expressions and scripts. */ /* ** SETTING: tcl-setup width=40 versionable block-text ** This is the setup script to be evaluated after creating ** and initializing the Tcl interpreter. By default, this ** is empty and no extra setup is performed. */ #endif /* FOSSIL_ENABLE_TCL */ #ifdef FOSSIL_ENABLE_TH1_DOCS /* ** SETTING: th1-docs boolean default=off ** If enabled, this allows embedded documentation files to contain ** arbitrary TH1 scripts that are evaluated on the server. If native ** Tcl integration is also enabled, this setting has the ** potential to allow anybody with check-in privileges to ** do almost anything that the associated operating system ** user account could do. Extreme caution should be used ** when enabling this setting. */ #endif #ifdef FOSSIL_ENABLE_TH1_HOOKS /* ** SETTING: th1-hooks boolean default=off ** If enabled, special TH1 commands will be called before and ** after any Fossil command or web page. */ #endif /* ** SETTING: th1-setup width=40 versionable block-text ** This is the setup script to be evaluated after creating ** and initializing the TH1 interpreter. By default, this ** is empty and no extra setup is performed. */ /* ** SETTING: th1-uri-regexp width=40 versionable block-text ** Specify which URI's are allowed in HTTP requests from ** TH1 scripts. If empty, no HTTP requests are allowed ** whatsoever. */ /* ** SETTING: uv-sync boolean default=off ** If true, automatically send unversioned files as part ** of a "fossil clone" or "fossil sync" command. The ** default is false, in which case the -u option is ** needed to clone or sync unversioned files. */ /* ** SETTING: web-browser width=30 ** A shell command used to launch your preferred ** web browser when given a URL as an argument. ** Defaults to "start" on windows, "open" on Mac, ** and "firefox" on Unix. */ /* ** Look up a control setting by its name. Return a pointer to the Setting ** object, or NULL if there is no such setting. ** ** If allowPrefix is true, then the Setting returned is the first one for ** which zName is a prefix of the Setting name. */ Setting *db_find_setting(const char *zName, int allowPrefix){ int lwr, mid, upr, c; int n = (int)strlen(zName) + !allowPrefix; int nSetting; const Setting *aSetting = setting_info(&nSetting); lwr = 0; upr = nSetting - 1; while( upr>=lwr ){ mid = (upr+lwr)/2; c = fossil_strncmp(zName, aSetting[mid].name, n); if( c<0 ){ upr = mid - 1; }else if( c>0 ){ lwr = mid + 1; }else{ if( allowPrefix ){ while( mid>lwr && fossil_strncmp(zName, aSetting[mid-1].name, n)==0 ){ mid--; } } return (Setting*)&aSetting[mid]; } } return 0; } /* ** COMMAND: settings ** COMMAND: unset* ** ** Usage: %fossil settings ?SETTING? ?VALUE? ?OPTIONS? ** or: %fossil unset SETTING ?OPTIONS? ** ** The "settings" command with no arguments lists all settings and their ** values. With just a SETTING name it shows the current value of that setting. ** With a VALUE argument it changes the property for the current repository. ** ** Settings marked as versionable are overridden by the contents of the ** file named .fossil-settings/PROPERTY in the check-out root, if that ** file exists. ** ** The "unset" command clears a setting. ** ** Settings can have both a "local" repository-only value and "global" value ** that applies to all repositories. The local values are stored in the ** "config" table of the repository and the global values are stored in the ** $HOME/.fossil file on unix or in the %LOCALAPPDATA%/_fossil file on Windows. ** If both a local and a global value exists for a setting, the local value ** takes precedence. This command normally operates on the local settings. ** Use the --global option to change global settings. ** ** Options: ** --global set or unset the given property globally instead of ** setting or unsetting it for the open repository only. ** ** --exact only consider exact name matches. ** ................................................................................ ** See also: configuration */ void setting_cmd(void){ int i; int globalFlag = find_option("global","g",0)!=0; int exactFlag = find_option("exact",0,0)!=0; int unsetFlag = g.argv[1][0]=='u'; int nSetting; const Setting *aSetting = setting_info(&nSetting); find_repository_option(); verify_all_options(); db_open_config(1, 0); if( !globalFlag ){ db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0); } if( !g.repositoryOpen ){ globalFlag = 1; } if( unsetFlag && g.argc!=3 ){ usage("PROPERTY ?-global?"); } if( g.argc==2 ){ for(i=0; i<nSetting; i++){ print_setting(&aSetting[i]); } }else if( g.argc==3 || g.argc==4 ){ const char *zName = g.argv[2]; int n = (int)strlen(zName); const Setting *pSetting = db_find_setting(zName, !exactFlag); if( pSetting==0 ){ |
Changes to src/delta.c.
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
|
int lenSrc, /* Length of the source file */ const char *zDelta, /* Delta to apply to the pattern */ int lenDelta, /* Length of the delta */ char *zOut /* Write the output into this preallocated buffer */ ){ unsigned int limit; unsigned int total = 0; #ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST char *zOrigOut = zOut; #endif limit = getInt(&zDelta, &lenDelta); if( *zDelta!='\n' ){ /* ERROR: size integer not terminated by "\n" */ return -1; ................................................................................ zDelta += cnt; lenDelta -= cnt; break; } case ';': { zDelta++; lenDelta--; zOut[0] = 0; #ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST if( cnt!=checksum(zOrigOut, total) ){ /* ERROR: bad checksum */ return -1; } #endif if( total!=limit ){ /* ERROR: generated size does not match predicted size */ |
|
|
|
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
|
int lenSrc, /* Length of the source file */ const char *zDelta, /* Delta to apply to the pattern */ int lenDelta, /* Length of the delta */ char *zOut /* Write the output into this preallocated buffer */ ){ unsigned int limit; unsigned int total = 0; #ifdef FOSSIL_ENABLE_DELTA_CKSUM_TEST char *zOrigOut = zOut; #endif limit = getInt(&zDelta, &lenDelta); if( *zDelta!='\n' ){ /* ERROR: size integer not terminated by "\n" */ return -1; ................................................................................ zDelta += cnt; lenDelta -= cnt; break; } case ';': { zDelta++; lenDelta--; zOut[0] = 0; #ifdef FOSSIL_ENABLE_DELTA_CKSUM_TEST if( cnt!=checksum(zOrigOut, total) ){ /* ERROR: bad checksum */ return -1; } #endif if( total!=limit ){ /* ERROR: generated size does not match predicted size */ |
Changes to src/diff.c.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 .... 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 .... 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 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 .... 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 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 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 .... 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 .... 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 |
#define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ #define DIFF_NUMSTAT ((u64)0x80000000) /* Show line count of changes */ #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ #define DIFF_SLOW_SBS (((u64)0x20)<<32) /* Better, but slower side-by-side */ /* ** These error messages are shared in multiple locations. They are defined ** here for consistency. */ #define DIFF_CANNOT_COMPUTE_BINARY \ "cannot compute difference between binary files\n" ................................................................................ struct AnnLine { /* Lines of the original files... */ const char *z; /* The text of the line */ short int n; /* Number of bytes (omitting trailing \n) */ short int iVers; /* Level at which tag was set */ } *aOrig; int nOrig; /* Number of elements in aOrig[] */ int nVers; /* Number of versions analyzed */ int bLimit; /* True if the iLimit was reached */ struct AnnVers { const char *zFUuid; /* File being analyzed */ const char *zMUuid; /* Check-in containing the file */ const char *zDate; /* Date of the check-in */ const char *zBgColor; /* Suggested background color */ const char *zUser; /* Name of user who did the check-in */ unsigned cnt; /* Number of lines contributed by this check-in */ ................................................................................ /* Clear out the from file */ free(p->c.aFrom); /* Return no errors */ return 0; } /* Annotation flags (any DIFF flag can be used as Annotation flag as well) */ #define ANN_FILE_VERS (((u64)0x20)<<32) /* File vers not commit vers */ #define ANN_FILE_ANCEST (((u64)0x40)<<32) /* Prefer checkins in the ANCESTOR */ /* ** Compute a complete annotation on a file. The file is identified ** by its filename number (filename.fnid) and check-in (mlink.mid). */ static void annotate_file( Annotator *p, /* The annotator */ int fnid, /* The name of the file to be annotated */ int mid, /* Use the version of the file in this check-in */ int iLimit, /* Limit the number of levels if greater than zero */ u64 annFlags /* Flags to alter the annotation */ ){ Blob toAnnotate; /* Text of the final (mid) version of the file */ Blob step; /* Text of previous revision */ int rid; /* Artifact ID of the file being annotated */ Stmt q; /* Query returning all ancestor versions */ Stmt ins; /* Inserts into the temporary VSEEN table */ int cnt = 0; /* Number of versions examined */ /* Initialize the annotation */ rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid); if( rid==0 ){ fossil_fatal("file #%d is unchanged in manifest #%d", fnid, mid); } if( !content_get(rid, &toAnnotate) ){ fossil_fatal("unable to retrieve content of artifact #%d", rid); } if( iLimit<=0 ) iLimit = 1000000000; blob_to_utf8_no_bom(&toAnnotate, 0); annotation_start(p, &toAnnotate, annFlags); db_begin_transaction(); db_multi_exec( "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);" "DELETE FROM vseen;" ); db_prepare(&ins, "INSERT OR IGNORE INTO vseen(rid) VALUES(:rid)"); db_prepare(&q, "SELECT (SELECT uuid FROM blob WHERE rid=mlink.fid)," " (SELECT uuid FROM blob WHERE rid=mlink.mid)," " date(event.mtime)," " coalesce(event.euser,event.user)," " mlink.pid" " FROM mlink, event" " WHERE mlink.fid=:rid" " AND event.objid=mlink.mid" " AND mlink.pid NOT IN vseen" " ORDER BY %s event.mtime", (annFlags & ANN_FILE_ANCEST)!=0 ? "(mlink.mid IN (SELECT rid FROM ancestor)) DESC,":"" ); db_bind_int(&q, ":rid", rid); if( iLimit==0 ) iLimit = 1000000000; while( rid && iLimit>cnt && db_step(&q)==SQLITE_ROW ){ int prevId = db_column_int(&q, 4); p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); if( p->nVers ){ content_get(rid, &step); blob_to_utf8_no_bom(&step, 0); annotation_step(p, &step, p->nVers-1, annFlags); blob_reset(&step); } p->nVers++; db_bind_int(&ins, ":rid", rid); db_step(&ins); db_reset(&ins); db_reset(&q); rid = prevId; db_bind_int(&q, ":rid", prevId); cnt++; } p->bLimit = iLimit==cnt; db_finalize(&q); db_finalize(&ins); db_end_transaction(0); } /* ** Return a color from a gradient. */ unsigned gradient_color(unsigned c1, unsigned c2, int n, int i){ ................................................................................ ** URL: /blame?checkin=ID&filename=FILENAME ** URL: /praise?checkin=ID&filename=FILENAME ** ** Show the most recent change to each line of a text file. /annotate shows ** the date of the changes and the check-in hash (with a link to the ** check-in). /blame and /praise also show the user who made the check-in. ** ** Query parameters: ** ** checkin=ID The manifest ID at which to start the annotation ** filename=FILENAME The filename. ** filevers Show file versions rather than check-in versions ** limit=N Limit the search depth to N ancestors ** log=BOOLEAN Show a log of versions analyzed ** w Ignore whitespace ** */ void annotation_page(void){ int mid; int fnid; int i; int iLimit; /* Depth limit */ u64 annFlags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); int showLog = 0; /* True to display the log */ int ignoreWs = 0; /* Ignore whitespace */ const char *zFilename; /* Name of file to annotate */ const char *zCI; /* The check-in containing zFilename */ Annotator ann; HQuery url; struct AnnVers *p; unsigned clr1, clr2, clr; int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */ /* Gather query parameters */ showLog = atoi(PD("log","1")); login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } if( exclude_spiders() ) return; load_control(); mid = name_to_typed_rid(PD("checkin","0"),"ci"); zFilename = P("filename"); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); if( mid==0 || fnid==0 ){ fossil_redirect_home(); } iLimit = atoi(PD("limit","20")); if( P("filevers") ) annFlags |= ANN_FILE_VERS; ignoreWs = P("w")!=0; if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS; if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ fossil_redirect_home(); } /* compute the annotation */ compute_direct_ancestors(mid); annotate_file(&ann, fnid, mid, iLimit, annFlags); zCI = ann.aVers[0].zMUuid; /* generate the web page */ style_header("Annotation For %h", zFilename); if( bBlame ){ url_initialize(&url, "blame"); }else{ url_initialize(&url, "annotate"); } url_add_parameter(&url, "checkin", P("checkin")); url_add_parameter(&url, "filename", zFilename); if( iLimit!=20 ){ url_add_parameter(&url, "limit", sqlite3_mprintf("%d", iLimit)); } url_add_parameter(&url, "log", showLog ? "1" : "0"); if( ignoreWs ){ url_add_parameter(&url, "w", ""); style_submenu_element("Show Whitespace Changes", "%s", url_render(&url, "w", 0, 0, 0)); }else{ style_submenu_element("Ignore Whitespace", "%s", url_render(&url, "w", "", 0, 0)); } if( showLog ){ style_submenu_element("Hide Log", "%s", url_render(&url, "log", "0", 0, 0)); }else{ style_submenu_element("Show Log", "%s", url_render(&url, "log", "1", 0, 0)); } if( ann.bLimit ){ char *z1, *z2; style_submenu_element("All Ancestors", "%s", url_render(&url, "limit", "-1", 0, 0)); z1 = sqlite3_mprintf("%d Ancestors", iLimit+20); z2 = sqlite3_mprintf("%d", iLimit+20); style_submenu_element(z1, "%s", url_render(&url, "limit", z2, 0, 0)); } if( iLimit>20 ){ style_submenu_element("20 Ancestors", "%s", url_render(&url, "limit", "20", 0, 0)); } if( skin_detail_boolean("white-foreground") ){ clr1 = 0xa04040; clr2 = 0x4059a0; }else{ clr1 = 0xffb5b5; /* Recent changes: red (hot) */ clr2 = 0xb5e0ff; /* Older changes: blue (cold) */ } for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ clr = gradient_color(clr1, clr2, ann.nVers-1, i); ann.aVers[i].zBgColor = mprintf("#%06x", clr); } if( showLog ){ char *zLink = href("%R/finfo?name=%t&ci=%!S",zFilename,zCI); @ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2> @ <ol> for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) @ check-in %z(href("%R/info/%!S",p->zMUuid))%S(p->zMUuid)</a> @ artifact %z(href("%R/artifact/%!S",p->zFUuid))%S(p->zFUuid)</a> @ </span> #if 0 if( i>0 ){ char *zLink = xhref("target='infowindow'", "%R/fdiff?v1=%S&v2=%S&sbs=1", p->zFUuid,ann.aVers[0].zFUuid); @ %z(zLink)[diff-to-top]</a> if( i>1 ){ zLink = xhref("target='infowindow'", "%R/fdiff?v1=%S&v2=%S&sbs=1", p->zFUuid,p[-1].zFUuid); @ %z(zLink)[diff-to-previous]</a> } } #endif } @ </ol> @ <hr /> } if( !ann.bLimit ){ @ <h2>Origin for each line in @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a> @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2> iLimit = ann.nVers+10; }else{ @ <h2>Lines added by the %d(iLimit) most recent ancestors of @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a> @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2> } @ <pre> for(i=0; i<ann.nOrig; i++){ int iVers = ann.aOrig[i].iVers; char *z = (char*)ann.aOrig[i].z; int n = ann.aOrig[i].n; char zPrefix[300]; z[n] = 0; if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; if( bBlame ){ if( iVers>=0 ){ struct AnnVers *p = ann.aVers+iVers; char *zLink = xhref("target='infowindow'", "%R/info/%!S", p->zMUuid); sqlite3_snprintf(sizeof(zPrefix), zPrefix, "<span style='background-color:%s'>" "%s%.10s</a> %s</span> %13.13s:", p->zBgColor, zLink, p->zMUuid, p->zDate, p->zUser); fossil_free(zLink); }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%36s", ""); } }else{ if( iVers>=0 ){ struct AnnVers *p = ann.aVers+iVers; char *zLink = xhref("target='infowindow'", "%R/info/%!S", p->zMUuid); sqlite3_snprintf(sizeof(zPrefix), zPrefix, "<span style='background-color:%s'>" "%s%.10s</a> %s</span> %4d:", p->zBgColor, zLink, p->zMUuid, p->zDate, i+1); fossil_free(zLink); }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%22s%4d:", "", i+1); } } @ %s(zPrefix) %h(z) } @ </pre> style_footer(); ................................................................................ } /* ** COMMAND: annotate ** COMMAND: blame ** COMMAND: praise ** ** Usage: %fossil (annotate|blame|praise) ?OPTIONS? FILENAME ** ** Output the text of a file with markings to show when each line of ** the file was last modified. The "annotate" command shows line numbers ** and omits the username. The "blame" and "praise" commands show the user ** who made each check-in and omits the line number. ** ** Options: ** --filevers Show file version numbers rather than ** check-in versions ** -l|--log List all versions analyzed ** -n|--limit N Only look backwards in time by N versions ** -w|--ignore-all-space Ignore white space when comparing lines ** -Z|--ignore-trailing-space Ignore whitespace at line end ** ** See also: info, finfo, timeline */ void annotate_cmd(void){ int fnid; /* Filename ID */ int fid; /* File instance ID */ int mid; /* Manifest where file was checked in */ int cid; /* Checkout ID */ Blob treename; /* FILENAME translated to canonical form */ char *zFilename; /* Canonical filename */ Annotator ann; /* The annotation of the file */ int i; /* Loop counter */ const char *zLimit; /* The value to the -n|--limit option */ int iLimit; /* How far back in time to look */ int showLog; /* True to show the log */ int fileVers; /* Show file version instead of check-in versions */ u64 annFlags = 0; /* Flags to control annotation properties */ int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ bBlame = g.argv[1][0]!='a'; zLimit = find_option("limit","n",1); if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; iLimit = atoi(zLimit); showLog = find_option("log","l",0)!=0; if( find_option("ignore-trailing-space","Z",0)!=0 ){ annFlags = DIFF_IGNORE_EOLWS; } if( find_option("ignore-all-space","w",0)!=0 ){ annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ } ................................................................................ /* We should be done with options.. */ verify_all_options(); if( g.argc<3 ) { usage("FILENAME"); } file_tree_name(g.argv[2], &treename, 0, 1); zFilename = blob_str(&treename); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); if( fnid==0 ){ fossil_fatal("no such file: %s", zFilename); } fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename); if( fid==0 ){ fossil_fatal("not part of current checkout: %s", zFilename); } cid = db_lget_int("checkout", 0); if( cid == 0 ){ fossil_fatal("Not in a checkout"); } if( iLimit<=0 ) iLimit = 1000000000; compute_direct_ancestors(cid); mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor " " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid" " ORDER BY ancestor.generation ASC LIMIT 1", fid, fnid); if( mid==0 ){ fossil_fatal("unable to find manifest"); } annFlags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); annotate_file(&ann, fnid, mid, iLimit, annFlags); if( showLog ){ struct AnnVers *p; for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ fossil_print("version %3d: %s %S file %S\n", i+1, p->zDate, p->zMUuid, p->zFUuid); } fossil_print("---------------------------------------------------\n"); } for(i=0; i<ann.nOrig; i++){ int iVers = ann.aOrig[i].iVers; char *z = (char*)ann.aOrig[i].z; int n = ann.aOrig[i].n; struct AnnVers *p; if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; p = ann.aVers + iVers; if( bBlame ){ if( iVers>=0 ){ fossil_print("%S %s %13.13s: %.*s\n", fileVers ? p->zFUuid : p->zMUuid, p->zDate, p->zUser, n, z); }else{ fossil_print("%35s %.*s\n", "", n, z); } }else{ if( iVers>=0 ){ fossil_print("%S %s %5d: %.*s\n", fileVers ? p->zFUuid : p->zMUuid, p->zDate, i+1, n, z); }else{ fossil_print("%21s %5d: %.*s\n", "", i+1, n, z); } } } } |
| | > > > > > > > > > > > > > | < < < > | > | < > | | | < > > | | | > > > | > | < | > > < < < < > > > > > > > > > > > | < < > > > > < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | > | | < < > < < | > > > > > > > > | > > > > > > > > > > < > < < < < < < < < > > > > > > > > | | < > > > > > > > | > < < | | | > | > > > > < < > | | | | | < < | < < < > | | > < | < < < | < < < < < < < > > | < | < < < < < < < | > > > | > | | | | | | | < < < < < < < < < < < | < < < | | > > > > > > > > | | > | > > > > > | > | > | | | > | | | | | | > | | > > > > > > > > > > < > > > > > > > | < < < < < | | | < > | | | | > > < < > < < < < < | < < < < < < < < < < < < < < < < < | < > > | < > | > < | |
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 .... 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 .... 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 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 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 .... 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 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 .... 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 .... 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 |
#define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ #define DIFF_NUMSTAT ((u64)0x80000000) /* Show line count of changes */ #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ #define DIFF_SLOW_SBS (((u64)0x20)<<32) /* Better but slower side-by-side */ /* ** These error messages are shared in multiple locations. They are defined ** here for consistency. */ #define DIFF_CANNOT_COMPUTE_BINARY \ "cannot compute difference between binary files\n" ................................................................................ struct AnnLine { /* Lines of the original files... */ const char *z; /* The text of the line */ short int n; /* Number of bytes (omitting trailing \n) */ short int iVers; /* Level at which tag was set */ } *aOrig; int nOrig; /* Number of elements in aOrig[] */ int nVers; /* Number of versions analyzed */ int bMoreToDo; /* True if the limit was reached */ int origId; /* RID for the zOrigin version */ int showId; /* RID for the version being analyzed */ struct AnnVers { const char *zFUuid; /* File being analyzed */ const char *zMUuid; /* Check-in containing the file */ const char *zDate; /* Date of the check-in */ const char *zBgColor; /* Suggested background color */ const char *zUser; /* Name of user who did the check-in */ unsigned cnt; /* Number of lines contributed by this check-in */ ................................................................................ /* Clear out the from file */ free(p->c.aFrom); /* Return no errors */ return 0; } /* Return the current time as milliseconds since the Julian epoch */ static sqlite3_int64 current_time_in_milliseconds(void){ static sqlite3_vfs *clockVfs = 0; sqlite3_int64 t; if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ clockVfs->xCurrentTimeInt64(clockVfs, &t); }else{ double r; clockVfs->xCurrentTime(clockVfs, &r); t = (sqlite3_int64)(r*86400000.0); } return t; } /* ** Compute a complete annotation on a file. The file is identified by its ** filename and check-in name (NULL for current check-in). */ static void annotate_file( Annotator *p, /* The annotator */ const char *zFilename, /* The name of the file to be annotated */ const char *zRevision, /* Use the version of the file in this check-in */ const char *zLimit, /* Limit the number of versions analyzed */ const char *zOrigin, /* The origin check-in, or NULL for root-of-tree */ u64 annFlags /* Flags to alter the annotation */ ){ Blob toAnnotate; /* Text of the final (mid) version of the file */ Blob step; /* Text of previous revision */ Blob treename; /* FILENAME translated to canonical form */ int cid; /* Selected check-in ID */ int origid = 0; /* The origin ID or zero */ int rid; /* Artifact ID of the file being annotated */ int fnid; /* Filename ID */ Stmt q; /* Query returning all ancestor versions */ int cnt = 0; /* Number of versions analyzed */ int iLimit; /* Maximum number of versions to analyze */ sqlite3_int64 mxTime; /* Halt at this time if not already complete */ if( zLimit ){ if( strcmp(zLimit,"none")==0 ){ iLimit = 0; mxTime = 0; }else if( sqlite3_strglob("*[0-9]s", zLimit)==0 ){ iLimit = 0; mxTime = current_time_in_milliseconds() + 1000.0*atof(zLimit); }else{ iLimit = atoi(zLimit); if( iLimit<=0 ) iLimit = 30; mxTime = 0; } }else{ /* Default limit is as much as we can do in 1.000 seconds */ iLimit = 0; mxTime = current_time_in_milliseconds()+1000; } db_begin_transaction(); /* Get the artificate ID for the check-in begin analyzed */ if( zRevision ){ cid = name_to_typed_rid(zRevision, "ci"); }else{ db_must_be_within_tree(); cid = db_lget_int("checkout", 0); } origid = zOrigin ? name_to_typed_rid(zOrigin, "ci") : 0; /* Compute all direct ancestors of the check-in being analyzed into ** the "ancestor" table. */ if( origid ){ path_shortest_stored_in_ancestor_table(origid, cid); }else{ compute_direct_ancestors(cid); } /* Get filename ID */ file_tree_name(zFilename, &treename, 0, 1); zFilename = blob_str(&treename); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); db_prepare(&q, "SELECT DISTINCT" " (SELECT uuid FROM blob WHERE rid=mlink.fid)," " (SELECT uuid FROM blob WHERE rid=mlink.mid)," " date(event.mtime)," " coalesce(event.euser,event.user)," " mlink.fid" " FROM mlink, event, ancestor" " WHERE mlink.fnid=%d" " AND ancestor.rid=mlink.mid" " AND event.objid=mlink.mid" " AND mlink.mid!=mlink.pid" " ORDER BY ancestor.generation;", fnid ); while( db_step(&q)==SQLITE_ROW ){ if( cnt>=3 ){ /* Process at least 3 rows before imposing limits */ if( (iLimit>0 && cnt>=iLimit) || (cnt>0 && mxTime>0 && current_time_in_milliseconds()>mxTime) ){ p->bMoreToDo = 1; break; } } rid = db_column_int(&q, 4); if( cnt==0 ){ if( !content_get(rid, &toAnnotate) ){ fossil_fatal("unable to retrieve content of artifact #%d", rid); } blob_to_utf8_no_bom(&toAnnotate, 0); annotation_start(p, &toAnnotate, annFlags); p->bMoreToDo = origid!=0; p->origId = origid; p->showId = cid; } p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); if( cnt>0 ){ content_get(rid, &step); blob_to_utf8_no_bom(&step, 0); annotation_step(p, &step, p->nVers-1, annFlags); blob_reset(&step); } p->nVers++; cnt++; } db_finalize(&q); db_end_transaction(0); } /* ** Return a color from a gradient. */ unsigned gradient_color(unsigned c1, unsigned c2, int n, int i){ ................................................................................ ** URL: /blame?checkin=ID&filename=FILENAME ** URL: /praise?checkin=ID&filename=FILENAME ** ** Show the most recent change to each line of a text file. /annotate shows ** the date of the changes and the check-in hash (with a link to the ** check-in). /blame and /praise also show the user who made the check-in. ** ** Reverse Annotations: Normally, these web pages look at versions of ** FILENAME moving backwards in time back toward the root check-in. However, ** if the origin= query parameter is used to specify some future check-in ** (example: "origin=trunk") then these pages show changes moving towards ** that alternative origin. Thus using "origin=trunk" on an historical ** version of the file shows the first time each line in the file was been ** changed in subsequent check-ins. ** ** Query parameters: ** ** checkin=ID The check-in at which to start the annotation ** filename=FILENAME The filename. ** filevers=BOOLEAN Show file versions rather than check-in versions ** limit=LIMIT Limit the amount of analysis: ** "none" No limit ** "Xs" As much as can be computed in X seconds ** "N" N versions ** log=BOOLEAN Show a log of versions analyzed ** origin=ID The origin checkin. If unspecified, the root ** check-in over the entire repository is used. ** Specify "origin=trunk" or similar for a reverse ** annotation ** w=BOOLEAN Ignore whitespace ** */ void annotation_page(void){ int i; const char *zLimit; /* Depth limit */ u64 annFlags = DIFF_STRIP_EOLCR; int showLog; /* True to display the log */ int fileVers; /* Show file version instead of check-in versions */ int ignoreWs; /* Ignore whitespace */ const char *zFilename; /* Name of file to annotate */ const char *zRevision; /* Name of check-in from which to start annotation */ const char *zCI; /* The check-in containing zFilename */ const char *zOrigin; /* The origin of the analysis */ int szHash; /* Number of characters in %S display */ char *zLink; Annotator ann; HQuery url; struct AnnVers *p; unsigned clr1, clr2, clr; int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */ /* Gather query parameters */ login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } if( exclude_spiders() ) return; load_control(); zFilename = P("filename"); zRevision = PD("checkin",0); zOrigin = P("origin"); zLimit = P("limit"); showLog = PB("log"); fileVers = PB("filevers"); ignoreWs = PB("w"); if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS; /* compute the annotation */ annotate_file(&ann, zFilename, zRevision, zLimit, zOrigin, annFlags); zCI = ann.aVers[0].zMUuid; /* generate the web page */ style_header("Annotation For %h", zFilename); if( bBlame ){ url_initialize(&url, "blame"); }else{ url_initialize(&url, "annotate"); } url_add_parameter(&url, "checkin", P("checkin")); url_add_parameter(&url, "filename", zFilename); if( zLimit ){ url_add_parameter(&url, "limit", zLimit); } url_add_parameter(&url, "w", ignoreWs ? "1" : "0"); url_add_parameter(&url, "log", showLog ? "1" : "0"); url_add_parameter(&url, "filevers", fileVers ? "1" : "0"); style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); style_submenu_checkbox("log", "Log", 0, "toggle_annotation_log()"); style_submenu_checkbox("filevers", "Link to Files", 0, 0); if( ann.bMoreToDo ){ style_submenu_element("All Ancestors", "%s", url_render(&url, "limit", "none", 0, 0)); } if( skin_detail_boolean("white-foreground") ){ clr1 = 0xa04040; clr2 = 0x4059a0; }else{ clr1 = 0xffb5b5; /* Recent changes: red (hot) */ clr2 = 0xb5e0ff; /* Older changes: blue (cold) */ } for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ clr = gradient_color(clr1, clr2, ann.nVers-1, i); ann.aVers[i].zBgColor = mprintf("#%06x", clr); } @ <div id="annotation_log" style='display:%s(showLog?"block":"none");'> if( zOrigin ){ zLink = href("%R/finfo?name=%t&ci=%!S&orig=%!S",zFilename,zCI,zOrigin); }else{ zLink = href("%R/finfo?name=%t&ci=%!S",zFilename,zCI); } @ <h2>Versions of %z(zLink)%h(zFilename)</a> analyzed:</h2> @ <ol> for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) @ check-in %z(href("%R/info/%!S",p->zMUuid))%S(p->zMUuid)</a> @ artifact %z(href("%R/artifact/%!S",p->zFUuid))%S(p->zFUuid)</a> @ </span> } @ </ol> @ <hr /> @ </div> @ <script> @ function toggle_annotation_log(){ @ var w = gebi("annotation_log"); @ var x = document.forms["f01"].elements["log"].checked @ w.style.display = x ? "block" : "none"; @ } @ </script> if( !ann.bMoreToDo ){ assert( ann.origId==0 ); /* bMoreToDo always set for a point-to-point */ @ <h2>Origin for each line in @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a> @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2> }else if( ann.origId>0 ){ @ <h2>Lines of @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a> @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a> @ that are changed by the sequence of edits moving toward @ check-in %z(href("%R/info/%!S",zOrigin))%S(zOrigin)</a>:</h2> }else{ @ <h2>Lines added by the %d(ann.nVers) most recent ancestors of @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a> @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2> } @ <pre> szHash = 10; for(i=0; i<ann.nOrig; i++){ int iVers = ann.aOrig[i].iVers; char *z = (char*)ann.aOrig[i].z; int n = ann.aOrig[i].n; char zPrefix[300]; z[n] = 0; if( iVers<0 && !ann.bMoreToDo ) iVers = ann.nVers-1; if( bBlame ){ if( iVers>=0 ){ struct AnnVers *p = ann.aVers+iVers; const char *zUuid = fileVers ? p->zFUuid : p->zMUuid; char *zLink = xhref("target='infowindow'", "%R/info/%!S", zUuid); sqlite3_snprintf(sizeof(zPrefix), zPrefix, "<span style='background-color:%s'>" "%s%.10s</a> %s</span> %13.13s:", p->zBgColor, zLink, zUuid, p->zDate, p->zUser); fossil_free(zLink); }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%*s", szHash+26, ""); } }else{ if( iVers>=0 ){ struct AnnVers *p = ann.aVers+iVers; const char *zUuid = fileVers ? p->zFUuid : p->zMUuid; char *zLink = xhref("target='infowindow'", "%R/info/%!S", zUuid); sqlite3_snprintf(sizeof(zPrefix), zPrefix, "<span style='background-color:%s'>" "%s%.10s</a> %s</span> %4d:", p->zBgColor, zLink, zUuid, p->zDate, i+1); fossil_free(zLink); }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%*s%4d:",szHash+12,"",i+1); } } @ %s(zPrefix) %h(z) } @ </pre> style_footer(); ................................................................................ } /* ** COMMAND: annotate ** COMMAND: blame ** COMMAND: praise ** ** Usage: %fossil annotate|blame|praise ?OPTIONS? FILENAME ** ** Output the text of a file with markings to show when each line of the file ** was last modified. The version currently checked out is shown by default. ** Other versions may be specified using the -r option. The "annotate" command ** shows line numbers and omits the username. The "blame" and "praise" commands ** show the user who made each check-in. ** ** Reverse Annotations: Normally, these commands look at versions of ** FILENAME moving backwards in time back toward the root check-in, and ** thus the output shows the most recent change to each line. However, ** if the -o|--origin option is used to specify some future check-in ** (example: "-o trunk") then these commands show changes moving towards ** that alternative origin. Thus using "-o trunk" on an historical version ** of the file shows the first time each line in the file was been changed ** by subsequent check-ins. ** ** Options: ** --filevers Show file version numbers rather than ** check-in versions ** -r|--revision VERSION The specific check-in containing the file ** -l|--log List all versions analyzed ** -n|--limit LIMIT Limit the amount of analysis: ** N Up to N versions ** Xs As much as possible in X seconds ** none No limit ** -o|--origin VERSION The origin check-in. By default this is the ** root of the repository. Set to "trunk" or ** similar for a reverse annotation. ** -w|--ignore-all-space Ignore white space when comparing lines ** -Z|--ignore-trailing-space Ignore whitespace at line end ** ** See also: info, finfo, timeline */ void annotate_cmd(void){ const char *zRevision; /* Revision name, or NULL for current check-in */ Annotator ann; /* The annotation of the file */ int i; /* Loop counter */ const char *zLimit; /* The value to the -n|--limit option */ const char *zOrig; /* The value for -o|--origin */ int showLog; /* True to show the log */ int fileVers; /* Show file version instead of check-in versions */ u64 annFlags = 0; /* Flags to control annotation properties */ int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ int szHash; /* Display size of a version hash */ bBlame = g.argv[1][0]!='a'; zRevision = find_option("r","revision",1); zLimit = find_option("limit","n",1); zOrig = find_option("origin","o",1); showLog = find_option("log","l",0)!=0; if( find_option("ignore-trailing-space","Z",0)!=0 ){ annFlags = DIFF_IGNORE_EOLWS; } if( find_option("ignore-all-space","w",0)!=0 ){ annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ } ................................................................................ /* We should be done with options.. */ verify_all_options(); if( g.argc<3 ) { usage("FILENAME"); } annFlags |= DIFF_STRIP_EOLCR; annotate_file(&ann, g.argv[2], zRevision, zLimit, zOrig, annFlags); if( showLog ){ struct AnnVers *p; for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ fossil_print("version %3d: %s %S file %S\n", i+1, p->zDate, p->zMUuid, p->zFUuid); } fossil_print("---------------------------------------------------\n"); } szHash = length_of_S_display(); for(i=0; i<ann.nOrig; i++){ int iVers = ann.aOrig[i].iVers; char *z = (char*)ann.aOrig[i].z; int n = ann.aOrig[i].n; struct AnnVers *p; if( iVers<0 && !ann.bMoreToDo ) iVers = ann.nVers-1; if( bBlame ){ if( iVers>=0 ){ p = ann.aVers + iVers; fossil_print("%S %s %13.13s: %.*s\n", fileVers ? p->zFUuid : p->zMUuid, p->zDate, p->zUser, n, z); }else{ fossil_print("%*s %.*s\n", szHash+26, "", n, z); } }else{ if( iVers>=0 ){ p = ann.aVers + iVers; fossil_print("%S %s %5d: %.*s\n", fileVers ? p->zFUuid : p->zMUuid, p->zDate, i+1, n, z); }else{ fossil_print("%*s %5d: %.*s\n", szHash+11, "", i+1, n, z); } } } } |
Changes to src/diffcmd.c.
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
blob_reset(&nameFile1); blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); }while( file_access(blob_str(&nameFile1),F_OK)==0 ); blob_write_to_file(pFile1, blob_str(&nameFile1)); /* Construct the external diff command */ blob_zero(&cmd); blob_appendf(&cmd, "%s ", zDiffCmd); if( fSwapDiff ){ shell_escape(&cmd, zFile2); blob_append(&cmd, " ", 1); shell_escape(&cmd, blob_str(&nameFile1)); }else{ shell_escape(&cmd, blob_str(&nameFile1)); blob_append(&cmd, " ", 1); shell_escape(&cmd, zFile2); } /* Run the external diff command */ fossil_system(blob_str(&cmd)); /* Delete the temporary file and clean up memory used */ file_delete(blob_str(&nameFile1)); ................................................................................ file_tempname(&temp1, blob_str(&prefix1)); file_tempname(&temp2, blob_str(&prefix2)); blob_write_to_file(pFile1, blob_str(&temp1)); blob_write_to_file(pFile2, blob_str(&temp2)); /* Construct the external diff command */ blob_zero(&cmd); blob_appendf(&cmd, "%s ", zDiffCmd); shell_escape(&cmd, blob_str(&temp1)); blob_append(&cmd, " ", 1); shell_escape(&cmd, blob_str(&temp2)); /* Run the external diff command */ fossil_system(blob_str(&cmd)); /* Delete the temporary file and clean up memory used */ file_delete(blob_str(&temp1)); file_delete(blob_str(&temp2)); |
|
|
<
|
|
<
|
|
|
<
|
|
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
|
blob_reset(&nameFile1); blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); }while( file_access(blob_str(&nameFile1),F_OK)==0 ); blob_write_to_file(pFile1, blob_str(&nameFile1)); /* Construct the external diff command */ blob_zero(&cmd); blob_append(&cmd, zDiffCmd, -1); if( fSwapDiff ){ blob_append_escaped_arg(&cmd, zFile2); blob_append_escaped_arg(&cmd, blob_str(&nameFile1)); }else{ blob_append_escaped_arg(&cmd, blob_str(&nameFile1)); blob_append_escaped_arg(&cmd, zFile2); } /* Run the external diff command */ fossil_system(blob_str(&cmd)); /* Delete the temporary file and clean up memory used */ file_delete(blob_str(&nameFile1)); ................................................................................ file_tempname(&temp1, blob_str(&prefix1)); file_tempname(&temp2, blob_str(&prefix2)); blob_write_to_file(pFile1, blob_str(&temp1)); blob_write_to_file(pFile2, blob_str(&temp2)); /* Construct the external diff command */ blob_zero(&cmd); blob_append(&cmd, zDiffCmd, -1); blob_append_escaped_arg(&cmd, blob_str(&temp1)); blob_append_escaped_arg(&cmd, blob_str(&temp2)); /* Run the external diff command */ fossil_system(blob_str(&cmd)); /* Delete the temporary file and clean up memory used */ file_delete(blob_str(&temp1)); file_delete(blob_str(&temp2)); |
Changes to src/dispatch.c.
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 .. 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 ... 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 ... 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 ... 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 ... 293 294 295 296 297 298 299 300 301 302 303 304 305 306 ... 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 ... 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 ... 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
** that implement those commands and web pages and their associated help ** text. */ #include "config.h" #include <assert.h> #include "dispatch.h" #if INTERFACE /* ** An instance of this object defines everything we need to know about an ** individual command or webpage. */ struct CmdOrPage { const char *zName; /* Name. Webpages start with "/". Commands do not */ void (*xFunc)(void); /* Function that implements the command or webpage */ const char *zHelp; /* Raw help text */ unsigned int eCmdFlags; /* Flags */ }; /*************************************************************************** ** These macros must match similar macros in mkindex.c ** Allowed values for CmdOrPage.eCmdFlags. */ #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */ #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */ #define CMDFLAG_TEST 0x0004 /* Commands for testing only */ #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */ #define CMDFLAG_COMMAND 0x0010 /* A command */ /**************************************************************************/ /* Values for the 2nd parameter to dispatch_name_search() */ #define CMDFLAG_ANY 0x0018 /* Match anything */ #define CMDFLAG_PREFIX 0x0020 /* Prefix match is ok */ #endif /* INTERFACE */ /* ** The page_index.h file contains the definition for aCommand[] - an array ** of CmdOrPage objects that defines all available commands and webpages ** known to Fossil. ................................................................................ ** source code files looking for header comments on the functions that ** implement command and webpages. */ #include "page_index.h" #define MX_COMMAND count(aCommand) /* ** Given a command or webpage name in zName, find the corresponding CmdOrPage ** object and return a pointer to that object in *ppCmd. ** ** The eType field is CMDFLAG_COMMAND to lookup commands or CMDFLAG_WEBPAGE ** to look up webpages or CMDFLAG_ANY to look for either. If the CMDFLAG_PREFIX ** flag is set, then a prefix match is allowed. ** ** Return values: ** 0: Success. *ppCmd is set to the appropriate CmdOrPage ** 1: Not found. ** 2: Ambiguous. Two or more entries match. */ int dispatch_name_search( ................................................................................ lwr = mid + 1; } } if( (eType & CMDFLAG_PREFIX)!=0 && lwr<MX_COMMAND && strncmp(zName, aCommand[lwr].zName, nName)==0 ){ if( lwr<MX_COMMAND-1 && strncmp(zName, aCommand[lwr+1].zName, nName)==0 ){ return 2; /* Ambiguous prefix */ }else{ *ppCmd = &aCommand[lwr]; return 0; /* Prefix match */ } } return 1; /* Not found */ } /* ** Fill Blob with a space-separated list of all command names that ** match the prefix zPrefix. */ void dispatch_matching_names(const char *zPrefix, Blob *pList){ int i; ................................................................................ ** Defaults to just the CLI commands. Specify --www to see only the ** web pages, or --everything to see both commands and pages. ** ** Options: ** -e|--everything Show all commands and pages. ** -t|--test Include test- commands ** -w|--www Show WWW pages. ** -h|--html Transform output to HTML. */ void test_all_help_cmd(void){ int i; int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER; int useHtml = find_option("html","h",0)!=0; if( find_option("www","w",0) ){ mask = CMDFLAG_WEBPAGE; } if( find_option("everything","e",0) ){ mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER | CMDFLAG_WEBPAGE; } if( find_option("test","t",0) ){ mask |= CMDFLAG_TEST; } if( useHtml ) fossil_print("<!--\n"); fossil_print("Help text for:\n"); if( mask & CMDFLAG_1ST_TIER ) fossil_print(" * Commands\n"); if( mask & CMDFLAG_2ND_TIER ) fossil_print(" * Auxiliary commands\n"); if( mask & CMDFLAG_TEST ) fossil_print(" * Test commands\n"); if( mask & CMDFLAG_WEBPAGE ) fossil_print(" * Web pages\n"); if( useHtml ){ fossil_print("-->\n"); fossil_print("<!-- start_all_help -->\n"); }else{ fossil_print("---\n"); } for(i=0; i<MX_COMMAND; i++){ ................................................................................ } /* ** WEBPAGE: help ** URL: /help?name=CMD ** ** Show the built-in help text for CMD. CMD can be a command-line interface ** command or a page name from the web interface. */ void help_page(void){ const char *zCmd = P("cmd"); if( zCmd==0 ) zCmd = P("name"); if( zCmd && *zCmd ){ int rc; const CmdOrPage *pCmd = 0; style_header("Help: %s", zCmd); style_submenu_element("Command-List", "%s/help", g.zTop); if( *zCmd=='/' ){ /* Some of the webpages require query parameters in order to work. ** @ <h1>The "<a href='%R%s(zCmd)'>%s(zCmd)</a>" page:</h1> */ @ <h1>The "%h(zCmd)" page:</h1> }else{ @ <h1>The "%h(zCmd)" command:</h1> } rc = dispatch_name_search(zCmd, CMDFLAG_ANY, &pCmd); if( rc==1 ){ @ unknown command: %h(zCmd) }else if( rc==2 ){ @ ambiguous command prefix: %h(zCmd) }else{ if( pCmd->zHelp[0]==0 ){ @ no help available for the %h(pCmd->zName) command }else{ @ <blockquote> help_to_html(pCmd->zHelp, cgi_output_blob()); @ </blockquote> } } }else{ int i, j, n; style_header("Help"); @ <h1>Available commands:</h1> @ <table border="0"><tr> for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( '/'==*z || strncmp(z,"test",4)==0 ) continue; j++; } ................................................................................ } } if( j>0 ){ @ </ul></td> } @ </tr></table> @ <h1>Available web UI pages:</h1> @ <table border="0"><tr> for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( '/'!=*z ) continue; j++; } ................................................................................ } } if( j>0 ){ @ </ul></td> } @ </tr></table> @ <h1>Unsupported commands:</h1> @ <table border="0"><tr> for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( strncmp(z,"test",4)!=0 ) continue; j++; } n = (j+3)/4; for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( strncmp(z,"test",4)!=0 ) continue; if( j==0 ){ @ <td valign="top"><ul> } if( aCommand[i].zHelp[0] ){ @ <li><a href="%R/help?cmd=%s(z)">%s(z)</a></li> }else{ @ <li>%s(z)</li> } j++; ................................................................................ } multi_column_list(aCmd, nCmd); } /* ** COMMAND: help ** ** Usage: %fossil help COMMAND ** or: %fossil COMMAND --help ** ** Display information on how to use COMMAND. To display a list of ** available commands use one of: ** ** %fossil help Show common commands ** %fossil help -a|--all Show both common and auxiliary commands ** %fossil help -t|--test Show test commands only ** %fossil help -x|--aux Show auxiliary commands only ** %fossil help -w|--www Show list of WWW pages */ void help_cmd(void){ int rc; int isPage = 0; const char *z; const char *zCmdOrPage; const char *zCmdOrPagePlural; const CmdOrPage *pCmd = 0; if( g.argc<3 ){ z = g.argv[0]; fossil_print( "Usage: %s help COMMAND\n" "Common COMMANDs: (use \"%s help -a|--all\" for a complete list)\n", z, z); command_list(0, CMDFLAG_1ST_TIER); version_cmd(); return; } if( find_option("all","a",0) ){ command_list(0, CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER); ................................................................................ else if( find_option("aux","x",0) ){ command_list(0, CMDFLAG_2ND_TIER); return; } else if( find_option("test","t",0) ){ command_list(0, CMDFLAG_TEST); return; } isPage = ('/' == *g.argv[2]) ? 1 : 0; if(isPage){ zCmdOrPage = "page"; zCmdOrPagePlural = "pages"; }else{ zCmdOrPage = "command"; zCmdOrPagePlural = "commands"; } rc = dispatch_name_search(g.argv[2], CMDFLAG_ANY|CMDFLAG_PREFIX, &pCmd); if( rc==1 ){ fossil_print("unknown %s: %s\nAvailable %s:\n", zCmdOrPage, g.argv[2], zCmdOrPagePlural); command_list(0, isPage ? CMDFLAG_WEBPAGE : (0xff & ~CMDFLAG_WEBPAGE)); fossil_exit(1); }else if( rc==2 ){ fossil_print("ambiguous %s prefix: %s\nMatching %s:\n", zCmdOrPage, g.argv[2], zCmdOrPagePlural); command_list(g.argv[2], 0xff); fossil_exit(1); } z = pCmd->zHelp; if( z==0 ){ fossil_fatal("no help available for the %s %s", pCmd->zName, zCmdOrPage); } while( *z ){ if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){ fossil_print("%s", g.argv[0]); z += 7; }else{ putchar(*z); z++; } } putchar('\n'); } |
< | | | | | | | > > > > | | | | | | | > > > | > > | | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | | | > | | | | | > > > > | | | | | > > > > > > > > > > > > > > > > > > |
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 .. 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 ... 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 ... 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 ... 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 ... 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 ... 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 ... 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 ... 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
** that implement those commands and web pages and their associated help ** text. */ #include "config.h" #include <assert.h> #include "dispatch.h" #if INTERFACE /* ** An instance of this object defines everything we need to know about an ** individual command, webpage, or setting. */ struct CmdOrPage { const char *zName; /* Name. Webpages start with "/". Commands do not */ void (*xFunc)(void); /* Implementation function, or NULL for settings */ const char *zHelp; /* Raw help text */ unsigned int eCmdFlags; /* Flags */ }; /*************************************************************************** ** These macros must match similar macros in mkindex.c ** Allowed values for CmdOrPage.eCmdFlags. */ #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */ #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */ #define CMDFLAG_TEST 0x0004 /* Commands for testing only */ #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */ #define CMDFLAG_COMMAND 0x0010 /* A command */ #define CMDFLAG_SETTING 0x0020 /* A setting */ #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */ #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */ #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */ /**************************************************************************/ /* Values for the 2nd parameter to dispatch_name_search() */ #define CMDFLAG_ANY 0x0038 /* Match anything */ #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */ #endif /* INTERFACE */ /* ** The page_index.h file contains the definition for aCommand[] - an array ** of CmdOrPage objects that defines all available commands and webpages ** known to Fossil. ................................................................................ ** source code files looking for header comments on the functions that ** implement command and webpages. */ #include "page_index.h" #define MX_COMMAND count(aCommand) /* ** Given a command, webpage, or setting name in zName, find the corresponding ** CmdOrPage object and return a pointer to that object in *ppCmd. ** ** The eType field is CMDFLAG_COMMAND to look up commands, CMDFLAG_WEBPAGE to ** look up webpages, CMDFLAG_SETTING to look up settings, or CMDFLAG_ANY to look ** for any. If the CMDFLAG_PREFIX bit is set, then a prefix match is allowed. ** ** Return values: ** 0: Success. *ppCmd is set to the appropriate CmdOrPage ** 1: Not found. ** 2: Ambiguous. Two or more entries match. */ int dispatch_name_search( ................................................................................ lwr = mid + 1; } } if( (eType & CMDFLAG_PREFIX)!=0 && lwr<MX_COMMAND && strncmp(zName, aCommand[lwr].zName, nName)==0 ){ /* An inexact prefix match was found. Scan the name table to try to find * exactly one entry with this prefix and the requested type. */ for( mid=-1; lwr<MX_COMMAND && strncmp(zName, aCommand[lwr].zName, nName)==0; ++lwr ){ if( aCommand[lwr].eCmdFlags & eType ){ if( mid<0 ){ mid = lwr; /* Potential ambiguous prefix */ }else{ return 2; /* Confirmed ambiguous prefix */ } } } if( mid>=0 ){ *ppCmd = &aCommand[mid]; return 0; /* Prefix match */ } } return 1; /* Not found */ } /* ** zName is the name of a webpage (eType==CMDFLAGS_WEBPAGE) that does not ** exist in the dispatch table. Check to see if this webpage name exists ** as an alias in the CONFIG table of the repository. If it is, then make ** appropriate changes to the CGI environment and set *ppCmd to point to the ** aliased command. ** ** Return 0 if the command is successfully aliased. Return 1 if there ** is not alias for zName. Any kind of error in the alias value causes a ** error to be thrown. ** ** Alias entries in the CONFIG table have a "name" value of "walias:NAME" ** where NAME is the input page name. The value is a string of the form ** "NEWNAME?QUERYPARAMS". The ?QUERYPARAMS is optional. If present (and it ** usually is), then all query parameters are added to the CGI environment. ** Except, query parameters of the form "X!" cause any CGI X variable to be ** removed. */ int dispatch_alias(const char *zName, const CmdOrPage **ppCmd){ char *z; char *zQ; int i; z = db_text(0, "SELECT value FROM config WHERE name='walias:%q'",zName); if( z==0 ) return 1; for(i=0; z[i] && z[i]!='?'; i++){} if( z[i]=='?' ){ z[i] = 0; zQ = &z[i+1]; }else{ zQ = &z[i]; } if( dispatch_name_search(z, CMDFLAG_WEBPAGE, ppCmd) ){ fossil_fatal("\"%s\" aliased to \"%s\" but \"%s\" does not exist", zName, z, z); } z = zQ; while( *z ){ char *zName = z; char *zValue = 0; while( *z && *z!='=' && *z!='&' && *z!='!' ){ z++; } if( *z=='=' ){ *z = 0; z++; zValue = z; while( *z && *z!='&' ){ z++; } if( *z ){ *z = 0; z++; } dehttpize(zValue); }else if( *z=='!' ){ *(z++) = 0; cgi_delete_query_parameter(zName); zName = ""; }else{ if( *z ){ *z++ = 0; } zValue = ""; } if( fossil_islower(zName[0]) ){ cgi_replace_query_parameter(zName, zValue); } } return 0; } /* ** Fill Blob with a space-separated list of all command names that ** match the prefix zPrefix. */ void dispatch_matching_names(const char *zPrefix, Blob *pList){ int i; ................................................................................ ** Defaults to just the CLI commands. Specify --www to see only the ** web pages, or --everything to see both commands and pages. ** ** Options: ** -e|--everything Show all commands and pages. ** -t|--test Include test- commands ** -w|--www Show WWW pages. ** -s|--settings Show settings. ** -h|--html Transform output to HTML. */ void test_all_help_cmd(void){ int i; int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER; int useHtml = find_option("html","h",0)!=0; if( find_option("www","w",0) ){ mask = CMDFLAG_WEBPAGE; } if( find_option("everything","e",0) ){ mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER | CMDFLAG_WEBPAGE; } if( find_option("settings","s",0) ){ mask = CMDFLAG_SETTING; } if( find_option("test","t",0) ){ mask |= CMDFLAG_TEST; } if( useHtml ) fossil_print("<!--\n"); fossil_print("Help text for:\n"); if( mask & CMDFLAG_1ST_TIER ) fossil_print(" * Commands\n"); if( mask & CMDFLAG_2ND_TIER ) fossil_print(" * Auxiliary commands\n"); if( mask & CMDFLAG_TEST ) fossil_print(" * Test commands\n"); if( mask & CMDFLAG_WEBPAGE ) fossil_print(" * Web pages\n"); if( mask & CMDFLAG_SETTING ) fossil_print(" * Settings\n"); if( useHtml ){ fossil_print("-->\n"); fossil_print("<!-- start_all_help -->\n"); }else{ fossil_print("---\n"); } for(i=0; i<MX_COMMAND; i++){ ................................................................................ } /* ** WEBPAGE: help ** URL: /help?name=CMD ** ** Show the built-in help text for CMD. CMD can be a command-line interface ** command or a page name from the web interface or a setting. */ void help_page(void){ const char *zCmd = P("cmd"); if( zCmd==0 ) zCmd = P("name"); if( zCmd && *zCmd ){ int rc; const CmdOrPage *pCmd = 0; style_header("Help: %s", zCmd); style_submenu_element("Command-List", "%s/help", g.zTop); rc = dispatch_name_search(zCmd, CMDFLAG_ANY, &pCmd); if( *zCmd=='/' ){ /* Some of the webpages require query parameters in order to work. ** @ <h1>The "<a href='%R%s(zCmd)'>%s(zCmd)</a>" page:</h1> */ @ <h1>The "%h(zCmd)" page:</h1> }else if( rc==0 && (pCmd->eCmdFlags & CMDFLAG_SETTING)!=0 ){ @ <h1>The "%h(pCmd->zName)" setting:</h1> }else{ @ <h1>The "%h(zCmd)" command:</h1> } if( rc==1 ){ @ unknown command: %h(zCmd) }else if( rc==2 ){ @ ambiguous command prefix: %h(zCmd) }else{ if( pCmd->zHelp[0]==0 ){ @ No help available for "%h(pCmd->zName)" }else{ @ <blockquote> help_to_html(pCmd->zHelp, cgi_output_blob()); @ </blockquote> } } }else{ int i, j, n; style_header("Help"); @ <a name='commands'></a> @ <h1>Available commands:</h1> @ <table border="0"><tr> for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( '/'==*z || strncmp(z,"test",4)==0 ) continue; j++; } ................................................................................ } } if( j>0 ){ @ </ul></td> } @ </tr></table> @ <a name='webpages'></a> @ <h1>Available web UI pages:</h1> @ <table border="0"><tr> for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( '/'!=*z ) continue; j++; } ................................................................................ } } if( j>0 ){ @ </ul></td> } @ </tr></table> @ <a name='unsupported'></a> @ <h1>Unsupported commands:</h1> @ <table border="0"><tr> for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( strncmp(z,"test",4)!=0 ) continue; j++; } n = (j+3)/4; for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( strncmp(z,"test",4)!=0 ) continue; if( j==0 ){ @ <td valign="top"><ul> } if( aCommand[i].zHelp[0] ){ @ <li><a href="%R/help?cmd=%s(z)">%s(z)</a></li> }else{ @ <li>%s(z)</li> } j++; if( j>=n ){ @ </ul></td> j = 0; } } if( j>0 ){ @ </ul></td> } @ </tr></table> @ <a name='settings'></a> @ <h1>Settings:</h1> @ <table border="0"><tr> for(i=j=0; i<MX_COMMAND; i++){ if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)==0 ) continue; j++; } n = (j+4)/5; for(i=j=0; i<MX_COMMAND; i++){ const char *z = aCommand[i].zName; if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)==0 ) continue; if( j==0 ){ @ <td valign="top"><ul> } if( aCommand[i].zHelp[0] ){ @ <li><a href="%R/help?cmd=%s(z)">%s(z)</a></li> }else{ @ <li>%s(z)</li> } j++; ................................................................................ } multi_column_list(aCmd, nCmd); } /* ** COMMAND: help ** ** Usage: %fossil help TOPIC ** or: %fossil TOPIC --help ** ** Display information on how to use TOPIC, which may be a command, webpage, or ** setting. Webpage names begin with "/". To display a list of available ** topics, use one of: ** ** %fossil help Show common commands ** %fossil help -a|--all Show both common and auxiliary commands ** %fossil help -s|--settings Show setting names ** %fossil help -t|--test Show test commands only ** %fossil help -x|--aux Show auxiliary commands only ** %fossil help -w|--www Show list of webpages */ void help_cmd(void){ int rc; int isPage = 0; const char *z; const char *zCmdOrPage; const char *zCmdOrPagePlural; const CmdOrPage *pCmd = 0; if( g.argc<3 ){ z = g.argv[0]; fossil_print( "Usage: %s help TOPIC\n" "Common commands: (use \"%s help -a|--all\" for a complete list)\n", z, z); command_list(0, CMDFLAG_1ST_TIER); version_cmd(); return; } if( find_option("all","a",0) ){ command_list(0, CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER); ................................................................................ else if( find_option("aux","x",0) ){ command_list(0, CMDFLAG_2ND_TIER); return; } else if( find_option("test","t",0) ){ command_list(0, CMDFLAG_TEST); return; } else if( find_option("setting","s",0) ){ command_list(0, CMDFLAG_SETTING); return; } isPage = ('/' == *g.argv[2]) ? 1 : 0; if(isPage){ zCmdOrPage = "page"; zCmdOrPagePlural = "pages"; }else{ zCmdOrPage = "command or setting"; zCmdOrPagePlural = "commands and settings"; } rc = dispatch_name_search(g.argv[2], CMDFLAG_ANY|CMDFLAG_PREFIX, &pCmd); if( rc==1 ){ fossil_print("unknown %s: %s\nConsider using:\n", zCmdOrPage, g.argv[2]); fossil_print(" fossil help -a ;# show all commands\n"); fossil_print(" fossil help -w ;# show all web-pages\n"); fossil_print(" fossil help -s ;# show all settings\n"); fossil_exit(1); }else if( rc==2 ){ fossil_print("ambiguous %s prefix: %s\nMatching %s:\n", zCmdOrPage, g.argv[2], zCmdOrPagePlural); command_list(g.argv[2], 0xff); fossil_exit(1); } z = pCmd->zHelp; if( z==0 ){ fossil_fatal("no help available for the %s %s", pCmd->zName, zCmdOrPage); } if( pCmd->eCmdFlags & CMDFLAG_SETTING ){ fossil_print("Setting: \"%s\"%s\n\n", pCmd->zName, (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : "" ); } while( *z ){ if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){ fossil_print("%s", g.argv[0]); z += 7; }else{ putchar(*z); z++; } } putchar('\n'); } /* ** Return a pointer to the setting information array. ** ** This routine provides access to the aSetting2[] array which is created ** by the mkindex utility program and included with <page_index.h>. */ const Setting *setting_info(int *pnCount){ if( pnCount ) *pnCount = (int)(sizeof(aSetting)/sizeof(aSetting[0])) - 1; return aSetting; } |
Changes to src/doc.c.
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 ... 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 ... 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 |
/* ** Look for a file named zName in the check-in with RID=vid. Load the content ** of that file into pContent and return the RID for the file. Or return 0 ** if the file is not found or could not be loaded. */ int doc_load_content(int vid, const char *zName, Blob *pContent){ int rid; /* The RID of the file being loaded */ if( !db_table_exists("repository","vcache") ){ db_multi_exec( "CREATE TABLE IF NOT EXISTS vcache(\n" " vid INTEGER, -- check-in ID\n" " fname TEXT, -- filename\n" " rid INTEGER, -- artifact ID\n" " PRIMARY KEY(vid,fname)\n" ") WITHOUT ROWID" ); } if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){ db_multi_exec( "DELETE FROM vcache;\n" "CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;\n" "INSERT INTO vcache(vid,fname,rid)" ................................................................................ rid = 0; } return rid; } /* ** Transfer content to the output. During the transfer, when text of ** the followign form is seen: ** ** href="$ROOT/ ** action="$ROOT/ ** ** Convert $ROOT to the root URI of the repository. Allow ' in place of " ** and any case for href. */ static void convert_href_and_output(Blob *pIn){ int i, base; int n = blob_size(pIn); char *z = blob_buffer(pIn); for(base=0, i=7; i<n; i++){ if( z[i]=='$' ................................................................................ ** specifies the title of the document in that case. ** ** For fossil-doc documents and for markdown documents, text of the ** form: "href='$ROOT/" or "action='$ROOT" has the $ROOT name expanded ** to the top-level of the repository. */ void doc_page(void){ const char *zName; /* Argument to the /doc page */ const char *zOrigName = "?"; /* Original document name */ const char *zMime; /* Document MIME type */ char *zCheckin = "tip"; /* The check-in holding the document */ char *zPathSuffix = ""; /* Text to append to g.zPath */ int vid = 0; /* Artifact of check-in */ int rid = 0; /* Artifact of file */ int i; /* Loop counter */ |
> | | | | | | |
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 ... 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 ... 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
/* ** Look for a file named zName in the check-in with RID=vid. Load the content ** of that file into pContent and return the RID for the file. Or return 0 ** if the file is not found or could not be loaded. */ int doc_load_content(int vid, const char *zName, Blob *pContent){ int writable = db_is_writeable("repository"); int rid; /* The RID of the file being loaded */ if( !db_table_exists("repository", "vcache") || !writable ){ db_multi_exec( "CREATE %s TABLE IF NOT EXISTS vcache(\n" " vid INTEGER, -- check-in ID\n" " fname TEXT, -- filename\n" " rid INTEGER, -- artifact ID\n" " PRIMARY KEY(vid,fname)\n" ") WITHOUT ROWID", writable ? "" : "TEMPORARY" ); } if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){ db_multi_exec( "DELETE FROM vcache;\n" "CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;\n" "INSERT INTO vcache(vid,fname,rid)" ................................................................................ rid = 0; } return rid; } /* ** Transfer content to the output. During the transfer, when text of ** the following form is seen: ** ** href="$ROOT/ ** action="$ROOT/ ** ** Convert $ROOT to the root URI of the repository. Allow ' in place of " ** and any case for href or action. */ static void convert_href_and_output(Blob *pIn){ int i, base; int n = blob_size(pIn); char *z = blob_buffer(pIn); for(base=0, i=7; i<n; i++){ if( z[i]=='$' ................................................................................ ** specifies the title of the document in that case. ** ** For fossil-doc documents and for markdown documents, text of the ** form: "href='$ROOT/" or "action='$ROOT" has the $ROOT name expanded ** to the top-level of the repository. */ void doc_page(void){ const char *zName = 0; /* Argument to the /doc page */ const char *zOrigName = "?"; /* Original document name */ const char *zMime; /* Document MIME type */ char *zCheckin = "tip"; /* The check-in holding the document */ char *zPathSuffix = ""; /* Text to append to g.zPath */ int vid = 0; /* Artifact of check-in */ int rid = 0; /* Artifact of file */ int i; /* Loop counter */ |
Changes to src/event.c.
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
nrid = content_put(&event);
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
if( manifest_crosslink(nrid, &event, MC_NONE)==0 ){
db_end_transaction(1);
return 0;
}
assert( blob_is_reset(&event) );
content_deltify(rid, nrid, 0);
db_end_transaction(0);
return 1;
}
/*
** WEBPAGE: technoteedit
** WEBPAGE: eventedit
|
| |
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
nrid = content_put(&event);
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
if( manifest_crosslink(nrid, &event, MC_NONE)==0 ){
db_end_transaction(1);
return 0;
}
assert( blob_is_reset(&event) );
content_deltify(rid, &nrid, 1, 0);
db_end_transaction(0);
return 1;
}
/*
** WEBPAGE: technoteedit
** WEBPAGE: eventedit
|
Changes to src/file.c.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 ... 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 ... 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 ... 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 ... 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 ... 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 ... 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 ... 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 .... 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 .... 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 .... 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 .... 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 .... 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 .... 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 |
** Fill stat buf with information received from stat() or lstat(). ** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on. ** */ static int fossil_stat( const char *zFilename, /* name of file or directory to inspect. */ struct fossilStat *buf, /* pointer to buffer where info should go. */ int isWd, /* non-zero to consider look at symlink itself. */ int forceWd /* non-zero to force look at symlink itself. */ ){ int rc; void *zMbcs = fossil_utf8_to_path(zFilename, 0); #if !defined(_WIN32) if( isWd && (forceWd || db_allow_symlinks(0)) ){ rc = lstat(zMbcs, buf); }else{ rc = stat(zMbcs, buf); } #else rc = win32_stat(zMbcs, buf, isWd); #endif ................................................................................ ** Return the number of errors. No error messages are generated. */ static int getStat(const char *zFilename, int isWd){ int rc = 0; if( zFilename==0 ){ if( fileStatValid==0 ) rc = 1; }else{ if( fossil_stat(zFilename, &fileStat, isWd, 0)!=0 ){ fileStatValid = 0; rc = 1; }else{ fileStatValid = 1; rc = 0; } } ................................................................................ ** Create symlink to file on Unix, or plain-text file with ** symlink target if "allow-symlinks" is off or we're on Windows. ** ** Arguments: target file (symlink will point to it), link file **/ void symlink_create(const char *zTargetFile, const char *zLinkFile){ #if !defined(_WIN32) if( db_allow_symlinks(0) ){ int i, nName; char *zName, zBuf[1000]; nName = strlen(zLinkFile); if( nName>=sizeof(zBuf) ){ zName = mprintf("%s", zLinkFile); }else{ ................................................................................ ** - PERM_REG for all other cases (regular file, directory, fifo, etc). */ int file_wd_perm(const char *zFilename){ #if !defined(_WIN32) if( !getStat(zFilename, 1) ){ if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 ) return PERM_EXE; else if( db_allow_symlinks(0) && S_ISLNK(fileStat.st_mode) ) return PERM_LNK; } #endif return PERM_REG; } /* ................................................................................ ** zFilename is a directory -OR- a symlink that points to a directory. ** Return 0 if zFilename does not exist. Return 2 if zFilename exists ** but is something other than a directory. */ int file_wd_isdir(const char *zFilename){ int rc; char *zFN; struct fossilStat dirFileStat; zFN = mprintf("%s", zFilename); file_simplify_name(zFN, -1, 0); memset(&dirFileStat, 0, sizeof(struct fossilStat)); rc = fossil_stat(zFN, &dirFileStat, 1, 1); if( rc ){ rc = 0; /* It does not exist at all. */ }else if( S_ISDIR(dirFileStat.st_mode) ){ rc = 1; /* It exists and is a real directory. */ }else if( !db_allow_symlinks(1) && S_ISLNK(dirFileStat.st_mode) ){ Blob content; blob_read_link(&content, zFN); /* It exists and is a link. */ rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */ blob_reset(&content); }else{ rc = 2; /* It exists and is something else. */ } ................................................................................ ** Set or clear the execute bit on a file. Return true if a change ** occurred and false if this routine is a no-op. */ int file_wd_setexe(const char *zFilename, int onoff){ int rc = 0; #if !defined(_WIN32) struct stat buf; if( fossil_stat(zFilename, &buf, 1, 0)!=0 || S_ISLNK(buf.st_mode) ) return 0; if( onoff ){ int targetMode = (buf.st_mode & 0444)>>2; if( (buf.st_mode & 0100)==0 ){ chmod(zFilename, buf.st_mode | targetMode); rc = 1; } }else{ ................................................................................ ** Create the tree of directories in which zFilename belongs, if that sequence ** of directories does not already exist. ** ** On success, return zero. On error, return errorReturn if positive, otherwise ** print an error message and abort. */ int file_mkfolder(const char *zFilename, int forceFlag, int errorReturn){ int i, nName, rc = 0; char *zName; nName = strlen(zFilename); zName = mprintf("%s", zFilename); nName = file_simplify_name(zName, nName, 0); for(i=1; i<nName; i++){ if( zName[i]=='/' ){ zName[i] = 0; #if defined(_WIN32) || defined(__CYGWIN__) /* ** On Windows, local path looks like: C:/develop/project/file.txt ** The if stops us from trying to create a directory of a drive letter ** C: in this example. */ if( !(i==2 && zName[1]==':') ){ #endif if( file_mkdir(zName, forceFlag) && file_wd_isdir(zName)!=1 ){ if (errorReturn <= 0) { fossil_fatal_recursive("unable to create directory %s", zName); } rc = errorReturn; break; } #if defined(_WIN32) || defined(__CYGWIN__) } #endif zName[i] = '/'; } } free(zName); return rc; } /* ................................................................................ file_canonical_name(zPath, &x, slash); fossil_print("%s[%s] -> [%s]\n", raw ? "RAW " : "", zPath, blob_buffer(&x)); blob_reset(&x); if( raw ){ int rc; struct fossilStat testFileStat; memset(&testFileStat, 0, sizeof(struct fossilStat)); rc = fossil_stat(zPath, &testFileStat, 0, 0); fossil_print(" stat_rc = %d\n", rc); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size); fossil_print(" stat_size = %s\n", zBuf); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime); fossil_print(" stat_mtime = %s\n", zBuf); fossil_print(" stat_mode = %d\n", testFileStat.st_mode); memset(&testFileStat, 0, sizeof(struct fossilStat)); rc = fossil_stat(zPath, &testFileStat, 1, 1); fossil_print(" l_stat_rc = %d\n", rc); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size); fossil_print(" l_stat_size = %s\n", zBuf); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime); fossil_print(" l_stat_mtime = %s\n", zBuf); fossil_print(" l_stat_mode = %d\n", testFileStat.st_mode); }else{ ................................................................................ ** display file system information about the files specified, if any. ** ** Options: ** ** --open-config Open the configuration database first. ** --slash Trailing slashes, if any, are retained. ** --reset Reset cached stat() info for each file. ** --symlinks BOOLEAN Force allow-symlinks on or off */ void cmd_test_file_environment(void){ int i; int slashFlag = find_option("slash",0,0)!=0; int resetFlag = find_option("reset",0,0)!=0; const char *forceSymlinks = find_option("symlinks",0,1); if( find_option("open-config", 0, 0)!=0 ){ Th_OpenConfig(1); } if( forceSymlinks ){ if( is_truth(forceSymlinks) ) g.allowSymlinks = 1; if( is_false(forceSymlinks) ) g.allowSymlinks = 0; } fossil_print("Th_IsLocalOpen() = %d\n", Th_IsLocalOpen()); fossil_print("Th_IsRepositoryOpen() = %d\n", Th_IsRepositoryOpen()); fossil_print("Th_IsConfigOpen() = %d\n", Th_IsConfigOpen()); fossil_print("filenames_are_case_sensitive() = %d\n", filenames_are_case_sensitive()); fossil_print("db_allow_symlinks_by_default() = %d\n", db_allow_symlinks_by_default()); fossil_print("db_allow_symlinks(0) = %d\n", db_allow_symlinks(0)); fossil_print("db_allow_symlinks(1) = %d\n", db_allow_symlinks(1)); for(i=2; i<g.argc; i++){ emitFileStat(g.argv[i], 1, slashFlag, resetFlag); emitFileStat(g.argv[i], 0, slashFlag, resetFlag); } } /* ** COMMAND: test-canonical-name ** ** Usage: %fossil test-canonical-name FILENAME... ** ** Test the operation of the canonical name generator. ** Also test Fossil's ability to measure attributes of a file. ** ** Options: ** ** --open-config Open the configuration database first. ** --slash Trailing slashes, if any, are retained. ** --reset Reset cached stat() info for each file. */ void cmd_test_canonical_name(void){ int i; int slashFlag = find_option("slash",0,0)!=0; int resetFlag = find_option("reset",0,0)!=0; if( find_option("open-config", 0, 0)!=0 ){ Th_OpenConfig(1); } for(i=2; i<g.argc; i++){ emitFileStat(g.argv[i], 0, slashFlag, resetFlag); } } /* ** Return TRUE if the given filename is canonical. ** ** Canonical names are full pathnames using "/" not "\" and which ................................................................................ } } /* ** COMMAND: test-relative-name ** ** Test the operation of the relative name generator. ** ** Options: ** ** --slash Trailing slashes, if any, are retained. */ void cmd_test_relative_name(void){ int i; Blob x; int slashFlag = find_option("slash",0,0)!=0; blob_zero(&x); for(i=2; i<g.argc; i++){ ................................................................................ ** ** Test the operation of the tree name generator. ** ** Options: ** --absolute Return an absolute path instead of a relative one. ** --case-sensitive B Enable or disable case-sensitive filenames. B is ** a boolean: "yes", "no", "true", "false", etc. ** --no-dir-symlinks Disables support for directory symlinks. */ void cmd_test_tree_name(void){ int i; Blob x; int absoluteFlag = find_option("absolute",0,0)!=0; db_find_and_open_repository(0,0); blob_zero(&x); ................................................................................ #if defined(_WIN32) const char *azDirs[] = { 0, /* GetTempPath */ 0, /* TEMP */ 0, /* TMP */ ".", }; #else static const char *azDirs[] = { 0, /* TMPDIR */ "/var/tmp", "/usr/tmp", "/tmp", "/temp", ................................................................................ char zRand[16]; #if defined(_WIN32) wchar_t zTmpPath[MAX_PATH]; if( GetTempPathW(MAX_PATH, zTmpPath) ){ azDirs[0] = fossil_path_to_utf8(zTmpPath); } azDirs[1] = fossil_getenv("TEMP"); azDirs[2] = fossil_getenv("TMP"); #else azDirs[0] = fossil_getenv("TMPDIR"); #endif ................................................................................ blob_appendf(pBuf, "%s/%s-%s.txt", zDir, zPrefix ? zPrefix : "", zRand); }while( file_size(blob_str(pBuf))>=0 ); #if defined(_WIN32) fossil_path_free((char *)azDirs[0]); fossil_path_free((char *)azDirs[1]); fossil_path_free((char *)azDirs[2]); #else fossil_path_free((char *)azDirs[0]); #endif } /* ** Return true if a file named zName exists and has identical content ** to the blob pContent. If zName does not exist or if the content is ** different in any way, then return false. */ int file_is_the_same(Blob *pContent, const char *zName){ |
| < | | | | < | < | < > | | | | | | < > | < < < < < | < < < < | | < < < < < < < < < | < < < < < < < > < | < < > > | > > > > > > > > > > > < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > |
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 ... 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 ... 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 ... 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 ... 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 ... 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 ... 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 ... 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 .... 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 .... 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 .... 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 .... 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 .... 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 .... 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 |
** Fill stat buf with information received from stat() or lstat(). ** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on. ** */ static int fossil_stat( const char *zFilename, /* name of file or directory to inspect. */ struct fossilStat *buf, /* pointer to buffer where info should go. */ int isWd /* non-zero to consider look at symlink itself. */ ){ int rc; void *zMbcs = fossil_utf8_to_path(zFilename, 0); #if !defined(_WIN32) if( isWd && db_allow_symlinks() ){ rc = lstat(zMbcs, buf); }else{ rc = stat(zMbcs, buf); } #else rc = win32_stat(zMbcs, buf, isWd); #endif ................................................................................ ** Return the number of errors. No error messages are generated. */ static int getStat(const char *zFilename, int isWd){ int rc = 0; if( zFilename==0 ){ if( fileStatValid==0 ) rc = 1; }else{ if( fossil_stat(zFilename, &fileStat, isWd)!=0 ){ fileStatValid = 0; rc = 1; }else{ fileStatValid = 1; rc = 0; } } ................................................................................ ** Create symlink to file on Unix, or plain-text file with ** symlink target if "allow-symlinks" is off or we're on Windows. ** ** Arguments: target file (symlink will point to it), link file **/ void symlink_create(const char *zTargetFile, const char *zLinkFile){ #if !defined(_WIN32) if( db_allow_symlinks() ){ int i, nName; char *zName, zBuf[1000]; nName = strlen(zLinkFile); if( nName>=sizeof(zBuf) ){ zName = mprintf("%s", zLinkFile); }else{ ................................................................................ ** - PERM_REG for all other cases (regular file, directory, fifo, etc). */ int file_wd_perm(const char *zFilename){ #if !defined(_WIN32) if( !getStat(zFilename, 1) ){ if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 ) return PERM_EXE; else if( db_allow_symlinks() && S_ISLNK(fileStat.st_mode) ) return PERM_LNK; } #endif return PERM_REG; } /* ................................................................................ ** zFilename is a directory -OR- a symlink that points to a directory. ** Return 0 if zFilename does not exist. Return 2 if zFilename exists ** but is something other than a directory. */ int file_wd_isdir(const char *zFilename){ int rc; char *zFN; zFN = mprintf("%s", zFilename); file_simplify_name(zFN, -1, 0); rc = getStat(zFN, 1); if( rc ){ rc = 0; /* It does not exist at all. */ }else if( S_ISDIR(fileStat.st_mode) ){ rc = 1; /* It exists and is a real directory. */ }else if( S_ISLNK(fileStat.st_mode) ){ Blob content; blob_read_link(&content, zFN); /* It exists and is a link. */ rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */ blob_reset(&content); }else{ rc = 2; /* It exists and is something else. */ } ................................................................................ ** Set or clear the execute bit on a file. Return true if a change ** occurred and false if this routine is a no-op. */ int file_wd_setexe(const char *zFilename, int onoff){ int rc = 0; #if !defined(_WIN32) struct stat buf; if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0; if( onoff ){ int targetMode = (buf.st_mode & 0444)>>2; if( (buf.st_mode & 0100)==0 ){ chmod(zFilename, buf.st_mode | targetMode); rc = 1; } }else{ ................................................................................ ** Create the tree of directories in which zFilename belongs, if that sequence ** of directories does not already exist. ** ** On success, return zero. On error, return errorReturn if positive, otherwise ** print an error message and abort. */ int file_mkfolder(const char *zFilename, int forceFlag, int errorReturn){ int nName, rc = 0; char *zName; nName = strlen(zFilename); zName = mprintf("%s", zFilename); nName = file_simplify_name(zName, nName, 0); while( nName>0 && zName[nName-1]!='/' ){ nName--; } if( nName ){ zName[nName-1] = 0; if( file_wd_isdir(zName)!=1 ){ rc = file_mkfolder(zName, forceFlag, errorReturn); if( rc==0 ){ if( file_mkdir(zName, forceFlag) && file_wd_isdir(zName)!=1 ){ if( errorReturn <= 0 ){ fossil_fatal_recursive("unable to create directory %s", zName); } rc = errorReturn; } } } } free(zName); return rc; } /* ................................................................................ file_canonical_name(zPath, &x, slash); fossil_print("%s[%s] -> [%s]\n", raw ? "RAW " : "", zPath, blob_buffer(&x)); blob_reset(&x); if( raw ){ int rc; struct fossilStat testFileStat; memset(&testFileStat, 0, sizeof(struct fossilStat)); rc = fossil_stat(zPath, &testFileStat, 0); fossil_print(" stat_rc = %d\n", rc); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size); fossil_print(" stat_size = %s\n", zBuf); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime); fossil_print(" stat_mtime = %s\n", zBuf); fossil_print(" stat_mode = %d\n", testFileStat.st_mode); memset(&testFileStat, 0, sizeof(struct fossilStat)); rc = fossil_stat(zPath, &testFileStat, 1); fossil_print(" l_stat_rc = %d\n", rc); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size); fossil_print(" l_stat_size = %s\n", zBuf); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime); fossil_print(" l_stat_mtime = %s\n", zBuf); fossil_print(" l_stat_mode = %d\n", testFileStat.st_mode); }else{ ................................................................................ ** display file system information about the files specified, if any. ** ** Options: ** ** --open-config Open the configuration database first. ** --slash Trailing slashes, if any, are retained. ** --reset Reset cached stat() info for each file. */ void cmd_test_file_environment(void){ int i; int slashFlag = find_option("slash",0,0)!=0; int resetFlag = find_option("reset",0,0)!=0; if( find_option("open-config", 0, 0)!=0 ){ Th_OpenConfig(1); } fossil_print("filenames_are_case_sensitive() = %d\n", filenames_are_case_sensitive()); fossil_print("db_allow_symlinks_by_default() = %d\n", db_allow_symlinks_by_default()); fossil_print("db_allow_symlinks() = %d\n", db_allow_symlinks()); for(i=2; i<g.argc; i++){ emitFileStat(g.argv[i], 1, slashFlag, resetFlag); emitFileStat(g.argv[i], 0, slashFlag, resetFlag); } } /* ** COMMAND: test-canonical-name ** ** Usage: %fossil test-canonical-name FILENAME... ** ** Test the operation of the canonical name generator. ** Also test Fossil's ability to measure attributes of a file. */ void cmd_test_canonical_name(void){ int i; Blob x; int slashFlag = find_option("slash",0,0)!=0; blob_zero(&x); for(i=2; i<g.argc; i++){ char zBuf[100]; const char *zName = g.argv[i]; file_canonical_name(zName, &x, slashFlag); fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x)); blob_reset(&x); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_size(zName)); fossil_print(" file_size = %s\n", zBuf); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_mtime(zName)); fossil_print(" file_mtime = %s\n", zBuf); fossil_print(" file_isfile = %d\n", file_wd_isfile(zName)); fossil_print(" file_isfile_or_link = %d\n",file_wd_isfile_or_link(zName)); fossil_print(" file_islink = %d\n", file_wd_islink(zName)); fossil_print(" file_isexe = %d\n", file_wd_isexe(zName)); fossil_print(" file_isdir = %d\n", file_wd_isdir(zName)); } } /* ** Return TRUE if the given filename is canonical. ** ** Canonical names are full pathnames using "/" not "\" and which ................................................................................ } } /* ** COMMAND: test-relative-name ** ** Test the operation of the relative name generator. */ void cmd_test_relative_name(void){ int i; Blob x; int slashFlag = find_option("slash",0,0)!=0; blob_zero(&x); for(i=2; i<g.argc; i++){ ................................................................................ ** ** Test the operation of the tree name generator. ** ** Options: ** --absolute Return an absolute path instead of a relative one. ** --case-sensitive B Enable or disable case-sensitive filenames. B is ** a boolean: "yes", "no", "true", "false", etc. */ void cmd_test_tree_name(void){ int i; Blob x; int absoluteFlag = find_option("absolute",0,0)!=0; db_find_and_open_repository(0,0); blob_zero(&x); ................................................................................ #if defined(_WIN32) const char *azDirs[] = { 0, /* GetTempPath */ 0, /* TEMP */ 0, /* TMP */ ".", }; char *z; #else static const char *azDirs[] = { 0, /* TMPDIR */ "/var/tmp", "/usr/tmp", "/tmp", "/temp", ................................................................................ char zRand[16]; #if defined(_WIN32) wchar_t zTmpPath[MAX_PATH]; if( GetTempPathW(MAX_PATH, zTmpPath) ){ azDirs[0] = fossil_path_to_utf8(zTmpPath); /* Removing trailing \ from the temp path */ z = (char*)azDirs[0]; i = (int)strlen(z)-1; if( i>0 && z[i]=='\\' ) z[i] = 0; } azDirs[1] = fossil_getenv("TEMP"); azDirs[2] = fossil_getenv("TMP"); #else azDirs[0] = fossil_getenv("TMPDIR"); #endif ................................................................................ blob_appendf(pBuf, "%s/%s-%s.txt", zDir, zPrefix ? zPrefix : "", zRand); }while( file_size(blob_str(pBuf))>=0 ); #if defined(_WIN32) fossil_path_free((char *)azDirs[0]); fossil_path_free((char *)azDirs[1]); fossil_path_free((char *)azDirs[2]); /* Change all \ characters in the windows path into / so that they can ** be safely passed to a subcommand, such as by gdiff */ z = blob_buffer(pBuf); for(i=0; z[i]; i++) if( z[i]=='\\' ) z[i] = '/'; #else fossil_path_free((char *)azDirs[0]); #endif } /* ** COMMAND: test-tempname ** Usage: fossil test-name BASENAME ... ** ** Generate temporary filenames derived from BASENAME */ void file_test_tempname(void){ int i; Blob x = BLOB_INITIALIZER; for(i=2; i<g.argc; i++){ file_tempname(&x, g.argv[i]); fossil_print("%s\n", blob_str(&x)); blob_reset(&x); } } /* ** Return true if a file named zName exists and has identical content ** to the blob pContent. If zName does not exist or if the content is ** different in any way, then return false. */ int file_is_the_same(Blob *pContent, const char *zName){ |
Changes to src/finfo.c.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 ... 283 284 285 286 287 288 289 290 291 292 293 294 295 296 ... 298 299 300 301 302 303 304 305 306 307 308 309 310 311 ... 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 ... 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 ... 442 443 444 445 446 447 448 449 450 451 452 453 454 455 ... 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 ... 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 ... 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 ... 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 ... 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 ... 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 |
** Options: ** -b|--brief display a brief (one line / revision) summary ** --case-sensitive B Enable or disable case-sensitive filenames. B is a ** boolean: "yes", "no", "true", "false", etc. ** -l|--log select log mode (the default) ** -n|--limit N Display the first N changes (default unlimited). ** N<=0 means no limit. ** --no-dir-symlinks Disables support for directory symlinks. ** --offset P skip P changes ** -p|--print select print mode ** -r|--revision R print the given revision (or ckout, if none is given) ** to stdout (only in print mode) ** -s|--status select status mode (print a status indicator for FILE) ** -W|--width <num> Width of lines (default is to auto-detect). Must be ** >22 or 0 (= no limit, resulting in a single line per ................................................................................ ** ** a=DATETIME Only show changes after DATETIME ** b=DATETIME Only show changes before DATETIME ** n=NUM Show the first NUM changes only ** brbg Background color by branch name ** ubg Background color by user name ** ci=UUID Ancestors of a particular check-in ** showid Show RID values for debugging ** ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in ** year-month-day form, it may be truncated, and it may also name a ** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM" ** (eastward). Either no timezone suffix or "Z" means UTC. */ ................................................................................ Stmt q; const char *zFilename; char zPrevDate[20]; const char *zA; const char *zB; int n; int baseCheckin; int fnid; Blob title; Blob sql; HQuery url; GraphContext *pGraph; int brBg = P("brbg")!=0; int uBg = P("ubg")!=0; ................................................................................ style_footer(); return; } if( g.perm.Admin ){ style_submenu_element("MLink Table", "%R/mlink?name=%t", zFilename); } if( baseCheckin ){ compute_direct_ancestors(baseCheckin); } url_add_parameter(&url, "name", zFilename); blob_zero(&sql); blob_append_sql(&sql, "SELECT" " datetime(min(event.mtime),toLocal())," /* Date of change */ " coalesce(event.ecomment, event.comment)," /* Check-in comment */ " coalesce(event.euser, event.user)," /* User who made chng */ " mlink.pid," /* Parent file rid */ " mlink.fid," /* File rid */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */ " event.bgcolor," /* Background color */ " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0" " AND tagxref.rid=mlink.mid)," /* Branchname */ " mlink.mid," /* check-in ID */ " mlink.pfnid" /* Previous filename */ " FROM mlink, event" " WHERE mlink.fnid=%d" " AND event.objid=mlink.mid", TAG_BRANCH, fnid ); if( (zA = P("a"))!=0 ){ blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA); url_add_parameter(&url, "a", zA); } if( (zB = P("b"))!=0 ){ ................................................................................ @ <p>SQL: %h(blob_str(&sql))</p> } blob_reset(&sql); blob_zero(&title); if( baseCheckin ){ char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); char *zLink = href("%R/info/%!S", zUuid); if( n>0 ){ blob_appendf(&title, "First %d ancestors of file ", n); }else{ blob_appendf(&title, "Ancestors of file "); } blob_appendf(&title,"<a href='%R/finfo?name=%T'>%h</a>", zFilename, zFilename); if( fShowId ) blob_appendf(&title, " (%d)", fnid); blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid); if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin); fossil_free(zUuid); }else{ blob_appendf(&title, "History of "); hyperlinked_path(zFilename, &title, 0, "tree", ""); if( fShowId ) blob_appendf(&title, " (%d)", fnid); } @ <h2>%b(&title)</h2> blob_reset(&title); ................................................................................ const char *zPUuid = db_column_text(&q, 5); const char *zUuid = db_column_text(&q, 6); const char *zCkin = db_column_text(&q,7); const char *zBgClr = db_column_text(&q, 8); const char *zBr = db_column_text(&q, 9); int fmid = db_column_int(&q, 10); int pfnid = db_column_int(&q, 11); int gidx; char zTime[10]; int nParent = 0; int aParent[GR_MAX_RAIL]; db_bind_int(&qparent, ":fid", frid); db_bind_int(&qparent, ":mid", fmid); ................................................................................ @ </td> if( zBgClr && zBgClr[0] ){ @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> }else{ @ <td class="timelineTableCell"> } if( zUuid ){ if( nParent==0 ){ @ <b>Added</b> }else if( pfnid ){ char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d", pfnid); @ <b>Renamed</b> from @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a> } @ %z(href("%R/artifact/%!S",zUuid))[%S(zUuid)]</a> if( fShowId ){ @ (%d(frid)) } @ part of check-in }else{ char *zNewName; zNewName = db_text(0, "SELECT name FROM filename WHERE fnid = " " (SELECT fnid FROM mlink" ................................................................................ } } hyperlink_to_uuid(zCkin); if( fShowId ){ @ (%d(fmid)) } @ %W(zCom) (user: hyperlink_to_user(zUser, zDate, ""); @ branch: %z(href("%R/timeline?t=%T&n=200",zBr))%h(zBr)</a>) if( g.perm.Hyperlink && zUuid ){ const char *z = zFilename; @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) @ [annotate]</a> @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin)) @ [blame]</a> @ %z(href("%R/timeline?n=200&uf=%!S",zUuid))[check-ins using]</a> ................................................................................ /* ** WEBPAGE: mlink ** URL: /mlink?name=FILENAME ** URL: /mlink?ci=NAME ** ** Show all MLINK table entries for a particular file, or for ** a particular check-in. This screen is intended for use by developers ** in debugging Fossil. */ void mlink_page(void){ const char *zFName = P("name"); const char *zCI = P("ci"); Stmt q; login_check_credentials(); ................................................................................ @ <h1>MLINK table for file @ <a href='%R/finfo?name=%t(zFName)'>%h(zFName)</a></h1> @ <div class='brlist'> @ <table id='mlinktable'> @ <thead><tr> @ <th>Date</th> @ <th>Check-in</th> @ <th>Parent Check-in</th> @ <th>Merge?</th> @ <th>New</th> @ <th>Old</th> @ <th>Exe Bit?</th> @ <th>Prior Name</th> @ </tr></thead> @ <tbody> while( db_step(&q)==SQLITE_ROW ){ const char *zDate = db_column_text(&q,0); const char *zCkin = db_column_text(&q,1); const char *zParent = db_column_text(&q,2); int isMerge = db_column_int(&q,3); ................................................................................ const char *zPid = db_column_text(&q,5); int isExe = db_column_int(&q,7); const char *zPrior = db_column_text(&q,8); @ <tr> @ <td><a href='%R/timeline?c=%!S(zCkin)'>%s(zDate)</a></td> @ <td><a href='%R/info/%!S(zCkin)'>%S(zCkin)</a></td> if( zParent ){ @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td> }else{ @ <td><i>(New)</i></td> } @ <td align='center'>%s(isMerge?"✓":"")</td> if( zFid ){ @ <td><a href='%R/info/%!S(zFid)'>%S(zFid)</a></td> }else{ ................................................................................ @ <h1>MLINK table for check-in %h(zCI)</h1> render_checkin_context(mid, 1); @ <hr /> @ <div class='brlist'> @ <table id='mlinktable'> @ <thead><tr> @ <th>File</th> @ <th>From</th> @ <th>Merge?</th> @ <th>New</th> @ <th>Old</th> @ <th>Exe Bit?</th> @ <th>Prior Name</th> @ </tr></thead> @ <tbody> while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q,0); const char *zFid = db_column_text(&q,1); const char *zPid = db_column_text(&q,3); const char *zPrior = db_column_text(&q,4); |
< > > > > > > > | > | > | | | > > > | > | > > > > > > > > | | | | | | | > > > > > | > | | > > > | | > > > > | | | | | | | |
43 44 45 46 47 48 49 50 51 52 53 54 55 56 ... 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 ... 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 ... 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 ... 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 ... 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 ... 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 ... 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 ... 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 ... 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 ... 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 ... 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
** Options: ** -b|--brief display a brief (one line / revision) summary ** --case-sensitive B Enable or disable case-sensitive filenames. B is a ** boolean: "yes", "no", "true", "false", etc. ** -l|--log select log mode (the default) ** -n|--limit N Display the first N changes (default unlimited). ** N<=0 means no limit. ** --offset P skip P changes ** -p|--print select print mode ** -r|--revision R print the given revision (or ckout, if none is given) ** to stdout (only in print mode) ** -s|--status select status mode (print a status indicator for FILE) ** -W|--width <num> Width of lines (default is to auto-detect). Must be ** >22 or 0 (= no limit, resulting in a single line per ................................................................................ ** ** a=DATETIME Only show changes after DATETIME ** b=DATETIME Only show changes before DATETIME ** n=NUM Show the first NUM changes only ** brbg Background color by branch name ** ubg Background color by user name ** ci=UUID Ancestors of a particular check-in ** orig=UUID If both ci and orig are supplied, only show those ** changes on a direct path from orig to ci. ** showid Show RID values for debugging ** ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in ** year-month-day form, it may be truncated, and it may also name a ** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM" ** (eastward). Either no timezone suffix or "Z" means UTC. */ ................................................................................ Stmt q; const char *zFilename; char zPrevDate[20]; const char *zA; const char *zB; int n; int baseCheckin; int origCheckin = 0; int fnid; Blob title; Blob sql; HQuery url; GraphContext *pGraph; int brBg = P("brbg")!=0; int uBg = P("ubg")!=0; ................................................................................ style_footer(); return; } if( g.perm.Admin ){ style_submenu_element("MLink Table", "%R/mlink?name=%t", zFilename); } if( baseCheckin ){ if( P("orig")!=0 ){ origCheckin = name_to_typed_rid(P("orig"),"ci"); path_shortest_stored_in_ancestor_table(origCheckin, baseCheckin); }else{ compute_direct_ancestors(baseCheckin); } } url_add_parameter(&url, "name", zFilename); blob_zero(&sql); blob_append_sql(&sql, "SELECT" " datetime(min(event.mtime),toLocal())," /* Date of change */ " coalesce(event.ecomment, event.comment)," /* Check-in comment */ " coalesce(event.euser, event.user)," /* User who made chng */ " mlink.pid," /* Parent file rid */ " mlink.fid," /* File rid */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */ " blob.uuid," /* Current file uuid */ " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */ " event.bgcolor," /* Background color */ " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0" " AND tagxref.rid=mlink.mid)," /* Branchname */ " mlink.mid," /* check-in ID */ " mlink.pfnid," /* Previous filename */ " blob.size" /* File size */ " FROM mlink, event, blob" " WHERE mlink.fnid=%d" " AND event.objid=mlink.mid" " AND mlink.fid=blob.rid", TAG_BRANCH, fnid ); if( (zA = P("a"))!=0 ){ blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA); url_add_parameter(&url, "a", zA); } if( (zB = P("b"))!=0 ){ ................................................................................ @ <p>SQL: %h(blob_str(&sql))</p> } blob_reset(&sql); blob_zero(&title); if( baseCheckin ){ char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); char *zLink = href("%R/info/%!S", zUuid); if( origCheckin ){ blob_appendf(&title, "Changes to file "); }else if( n>0 ){ blob_appendf(&title, "First %d ancestors of file ", n); }else{ blob_appendf(&title, "Ancestors of file "); } blob_appendf(&title,"<a href='%R/finfo?name=%T'>%h</a>", zFilename, zFilename); if( fShowId ) blob_appendf(&title, " (%d)", fnid); blob_append(&title, origCheckin ? " between " : " from ", -1); blob_appendf(&title, "check-in %z%S</a>", zLink, zUuid); if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin); fossil_free(zUuid); if( origCheckin ){ zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", origCheckin); zLink = href("%R/info/%!S", zUuid); blob_appendf(&title, " and check-in %z%S</a>", zLink, zUuid); fossil_free(zUuid); } }else{ blob_appendf(&title, "History of "); hyperlinked_path(zFilename, &title, 0, "tree", ""); if( fShowId ) blob_appendf(&title, " (%d)", fnid); } @ <h2>%b(&title)</h2> blob_reset(&title); ................................................................................ const char *zPUuid = db_column_text(&q, 5); const char *zUuid = db_column_text(&q, 6); const char *zCkin = db_column_text(&q,7); const char *zBgClr = db_column_text(&q, 8); const char *zBr = db_column_text(&q, 9); int fmid = db_column_int(&q, 10); int pfnid = db_column_int(&q, 11); int szFile = db_column_int(&q, 12); int gidx; char zTime[10]; int nParent = 0; int aParent[GR_MAX_RAIL]; db_bind_int(&qparent, ":fid", frid); db_bind_int(&qparent, ":mid", fmid); ................................................................................ @ </td> if( zBgClr && zBgClr[0] ){ @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> }else{ @ <td class="timelineTableCell"> } if( zUuid ){ if( origCheckin==0 ){ if( nParent==0 ){ @ <b>Added</b> }else if( pfnid ){ char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d", pfnid); @ <b>Renamed</b> from @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a> } } @ %z(href("%R/artifact/%!S",zUuid))[%S(zUuid)]</a> if( fShowId ){ int srcId = delta_source_rid(frid); if( srcId>0 ){ @ (%d(frid)←%d(srcId)) }else{ @ (%d(frid)) } } @ part of check-in }else{ char *zNewName; zNewName = db_text(0, "SELECT name FROM filename WHERE fnid = " " (SELECT fnid FROM mlink" ................................................................................ } } hyperlink_to_uuid(zCkin); if( fShowId ){ @ (%d(fmid)) } @ %W(zCom) (user: hyperlink_to_user(zUser, zDate, ","); @ branch: %z(href("%R/timeline?t=%T&n=200",zBr))%h(zBr)</a>, @ size: %d(szFile)) if( g.perm.Hyperlink && zUuid ){ const char *z = zFilename; @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) @ [annotate]</a> @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin)) @ [blame]</a> @ %z(href("%R/timeline?n=200&uf=%!S",zUuid))[check-ins using]</a> ................................................................................ /* ** WEBPAGE: mlink ** URL: /mlink?name=FILENAME ** URL: /mlink?ci=NAME ** ** Show all MLINK table entries for a particular file, or for ** a particular check-in. ** ** This screen is intended for use by Fossil developers to help ** in debugging Fossil itself. Ordinary Fossil users are not ** expected to know what the MLINK table is or why it is important. ** ** To avoid confusing ordinary users, this page is only available ** to adminstrators. */ void mlink_page(void){ const char *zFName = P("name"); const char *zCI = P("ci"); Stmt q; login_check_credentials(); ................................................................................ @ <h1>MLINK table for file @ <a href='%R/finfo?name=%t(zFName)'>%h(zFName)</a></h1> @ <div class='brlist'> @ <table id='mlinktable'> @ <thead><tr> @ <th>Date</th> @ <th>Check-in</th> @ <th>Parent<br>Check-in</th> @ <th>Merge?</th> @ <th>New</th> @ <th>Old</th> @ <th>Exe<br>Bit?</th> @ <th>Prior<br>Name</th> @ </tr></thead> @ <tbody> while( db_step(&q)==SQLITE_ROW ){ const char *zDate = db_column_text(&q,0); const char *zCkin = db_column_text(&q,1); const char *zParent = db_column_text(&q,2); int isMerge = db_column_int(&q,3); ................................................................................ const char *zPid = db_column_text(&q,5); int isExe = db_column_int(&q,7); const char *zPrior = db_column_text(&q,8); @ <tr> @ <td><a href='%R/timeline?c=%!S(zCkin)'>%s(zDate)</a></td> @ <td><a href='%R/info/%!S(zCkin)'>%S(zCkin)</a></td> if( zParent ){ @ <td><a href='%R/info/%!S(zParent)'>%S(zParent)</a></td> }else{ @ <td><i>(New)</i></td> } @ <td align='center'>%s(isMerge?"✓":"")</td> if( zFid ){ @ <td><a href='%R/info/%!S(zFid)'>%S(zFid)</a></td> }else{ ................................................................................ @ <h1>MLINK table for check-in %h(zCI)</h1> render_checkin_context(mid, 1); @ <hr /> @ <div class='brlist'> @ <table id='mlinktable'> @ <thead><tr> @ <th>File</th> @ <th>Parent<br>Check-in</th> @ <th>Merge?</th> @ <th>New</th> @ <th>Old</th> @ <th>Exe<br>Bit?</th> @ <th>Prior<br>Name</th> @ </tr></thead> @ <tbody> while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q,0); const char *zFid = db_column_text(&q,1); const char *zPid = db_column_text(&q,3); const char *zPrior = db_column_text(&q,4); |
Changes to src/hname.c.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
** if the hash does not match. */ int hname_verify_file_hash(const char *zFile, const char *zHash, int nHash){ int id = HNAME_ERROR; switch( nHash ){ case HNAME_LEN_SHA1: { Blob hash; sha1sum_file(zFile, &hash); if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1; blob_reset(&hash); break; } case HNAME_LEN_K256: { Blob hash; sha3sum_file(zFile, 256, &hash); if( memcmp(blob_buffer(&hash),zHash,64)==0 ) id = HNAME_LEN_K256; blob_reset(&hash); break; } } return id; } |
| | |
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
** if the hash does not match. */ int hname_verify_file_hash(const char *zFile, const char *zHash, int nHash){ int id = HNAME_ERROR; switch( nHash ){ case HNAME_LEN_SHA1: { Blob hash; if( sha1sum_file(zFile, &hash) ) break; if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1; blob_reset(&hash); break; } case HNAME_LEN_K256: { Blob hash; if( sha3sum_file(zFile, 256, &hash) ) break; if( memcmp(blob_buffer(&hash),zHash,64)==0 ) id = HNAME_LEN_K256; blob_reset(&hash); break; } } return id; } |
Changes to src/http_transport.c.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
..
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
|
if( pnSent ) *pnSent = transport.nSent; if( pnRcvd ) *pnRcvd = transport.nRcvd; if( resetFlag ){ transport.nSent = 0; transport.nRcvd = 0; } } /* ** Default SSH command */ #ifdef _WIN32 static const char zDefaultSshCmd[] = "plink -ssh -T"; #else ................................................................................ int transport_ssh_open(UrlData *pUrlData){ /* For SSH we need to create and run SSH fossil http ** to talk to the remote machine. */ char *zSsh; /* The base SSH command */ Blob zCmd; /* The SSH command */ char *zHost; /* The host name to contact */ int n; /* Size of prefix string */ socket_ssh_resolve_addr(pUrlData); zSsh = db_get("ssh-command", zDefaultSshCmd); blob_init(&zCmd, zSsh, -1); if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){ #ifdef _WIN32 blob_appendf(&zCmd, " -P %d", pUrlData->port); #else blob_appendf(&zCmd, " -p %d", pUrlData->port); #endif } if( g.fSshTrace ){ fossil_force_newline(); fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ } if( pUrlData->user && pUrlData->user[0] ){ zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name); }else{ zHost = mprintf("%s", pUrlData->name); } n = blob_size(&zCmd); blob_append(&zCmd, " ", 1); shell_escape(&zCmd, zHost); blob_append(&zCmd, " ", 1); shell_escape(&zCmd, mprintf("%s", pUrlData->fossil)); blob_append(&zCmd, " test-http", 10); if( pUrlData->path && pUrlData->path[0] ){ blob_append(&zCmd, " ", 1); shell_escape(&zCmd, mprintf("%s", pUrlData->path)); } if( g.fSshTrace ){ fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */ } free(zHost); popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); if( sshPid==0 ){ socket_set_errmsg("cannot start ssh tunnel using [%b]", &zCmd); } blob_reset(&zCmd); return sshPid==0; } |
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
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
...
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
|
if( pnSent ) *pnSent = transport.nSent; if( pnRcvd ) *pnRcvd = transport.nRcvd; if( resetFlag ){ transport.nSent = 0; transport.nRcvd = 0; } } /* ** Check zFossil to see if it is a reasonable "fossil" command to ** run on the server. Do not allow an attacker to substitute something ** like "/bin/rm". */ static int is_safe_fossil_command(const char *zFossil){ static const char *azSafe[] = { "*/fossil", "*/echo" }; int i; for(i=0; i<sizeof(azSafe)/sizeof(azSafe[0]); i++){ if( sqlite3_strglob(azSafe[i], zFossil)==0 ) return 1; if( strcmp(azSafe[i]+2, zFossil)==0 ) return 1; } return 0; } /* ** Default SSH command */ #ifdef _WIN32 static const char zDefaultSshCmd[] = "plink -ssh -T"; #else ................................................................................ int transport_ssh_open(UrlData *pUrlData){ /* For SSH we need to create and run SSH fossil http ** to talk to the remote machine. */ char *zSsh; /* The base SSH command */ Blob zCmd; /* The SSH command */ char *zHost; /* The host name to contact */ socket_ssh_resolve_addr(pUrlData); zSsh = db_get("ssh-command", zDefaultSshCmd); blob_init(&zCmd, zSsh, -1); if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){ #ifdef _WIN32 blob_appendf(&zCmd, " -P %d", pUrlData->port); #else blob_appendf(&zCmd, " -p %d", pUrlData->port); #endif } if( pUrlData->user && pUrlData->user[0] ){ zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name); blob_append_escaped_arg(&zCmd, zHost); fossil_free(zHost); }else{ blob_append_escaped_arg(&zCmd, pUrlData->name); } if( !is_safe_fossil_command(pUrlData->fossil) ){ fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on " "the server.", pUrlData->fossil); } blob_append_escaped_arg(&zCmd, pUrlData->fossil); blob_append(&zCmd, " test-http", 10); if( pUrlData->path && pUrlData->path[0] ){ blob_append_escaped_arg(&zCmd, pUrlData->path); }else{ fossil_fatal("ssh:// URI does not specify a path to the repository"); } if( g.fSshTrace ){ fossil_print("%s\n", blob_str(&zCmd)); /* Show the whole SSH command */ } popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); if( sshPid==0 ){ socket_set_errmsg("cannot start ssh tunnel using [%b]", &zCmd); } blob_reset(&zCmd); return sshPid==0; } |
Changes to src/info.c.
762 763 764 765 766 767 768 769 770 771 772 773 774 775 .... 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 .... 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 .... 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 .... 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 .... 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 .... 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 .... 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 .... 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 .... 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 .... 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 |
@ </td></tr> @ <tr><th>Other Links:</th> @ <td> @ %z(href("%R/tree?ci=%!S",zUuid))files</a> @ | %z(href("%R/fileage?name=%!S",zUuid))file ages</a> @ | %z(href("%R/tree?nofiles&type=tree&ci=%!S",zUuid))folders</a> @ | %z(href("%R/artifact/%!S",zUuid))manifest</a> if( g.anon.Write ){ @ | %z(href("%R/ci_edit?r=%!S",zUuid))edit</a> } @ </td> @ </tr> blob_reset(&projName); } ................................................................................ ** from=TAG Left side of the comparison ** to=TAG Right side of the comparison ** branch=TAG Show all changes on a particular branch ** v=BOOLEAN Default true. If false, only list files that have changed ** sbs=BOOLEAN Side-by-side diff if true. Unified diff if false ** glob=STRING only diff files matching this glob ** dc=N show N lines of context around each diff ** w ignore whitespace when computing diffs ** nohdr omit the description at the top of the page ** ** ** Show all differences between two check-ins. */ void vdiff_page(void){ int ridFrom, ridTo; int verboseFlag = 0; int sideBySide = 0; u64 diffFlags = 0; Manifest *pFrom, *pTo; ManifestFile *pFileFrom, *pFileTo; const char *zBranch; const char *zFrom; const char *zTo; const char *zRe; ................................................................................ style_submenu_element("Clear glob", "%R/vdiff?from=%T&to=%T&sbs=%d%s%s", zFrom, zTo, sideBySide, (verboseFlag && !sideBySide)?"&v":"", zW); }else{ style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo, zW); } if( sideBySide || verboseFlag ){ if( *zW ){ style_submenu_element("Show Whitespace Differences", "%R/vdiff?from=%T&to=%T&sbs=%d%s%s%T", zFrom, zTo, sideBySide, (verboseFlag && !sideBySide)?"&v":"", zGlob ? "&glob=" : "", zGlob ? zGlob : ""); }else{ style_submenu_element("Ignore Whitespace", "%R/vdiff?from=%T&to=%T&sbs=%d%s%s%T&w", zFrom, zTo, sideBySide, (verboseFlag && !sideBySide)?"&v":"", zGlob ? "&glob=" : "", zGlob ? zGlob : ""); } } style_header("Check-in Differences"); if( P("nohdr")==0 ){ @ <h2>Difference From:</h2><blockquote> checkin_description(ridFrom); @ </blockquote><h2>To:</h2><blockquote> checkin_description(ridTo); ................................................................................ db_prepare(&q, "SELECT filename.name, datetime(event.mtime,toLocal())," " coalesce(event.ecomment,event.comment)," " coalesce(event.euser,event.user)," " b.uuid, mlink.mperm," " coalesce((SELECT value FROM tagxref" " WHERE tagid=%d AND tagtype>0 AND rid=mlink.mid),'trunk')" " FROM mlink, filename, event, blob a, blob b" " WHERE filename.fnid=mlink.fnid" " AND event.objid=mlink.mid" " AND a.rid=mlink.fid" " AND b.rid=mlink.mid" " AND mlink.fid=%d" " ORDER BY filename.name, event.mtime /*sort*/", ................................................................................ const char *zName = db_column_text(&q, 0); const char *zDate = db_column_text(&q, 1); const char *zCom = db_column_text(&q, 2); const char *zUser = db_column_text(&q, 3); const char *zVers = db_column_text(&q, 4); int mPerm = db_column_int(&q, 5); const char *zBr = db_column_text(&q, 6); int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0; if( sameFilename && !showDetail ){ if( cnt==1 ){ @ %z(href("%R/whatis/%!S",zUuid))[more...]</a> } cnt++; continue; ................................................................................ @ at hyperlink_to_date(zDate,""); } 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/finfo?name=%T&ci=%!S",zName,zVers))[ancestry]</a> @ %z(href("%R/annotate?filename=%T&checkin=%!S",zName,zVers)) @ [annotate]</a> @ %z(href("%R/blame?filename=%T&checkin=%!S",zName,zVers)) @ [blame]</a> } ................................................................................ } return objType; } /* ** WEBPAGE: fdiff ** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN®ex=REGEX ** ** Two arguments, v1 and v2, identify the files to be diffed. Show the ** difference between the two artifacts. Show diff side by side unless sbs ** is 0. Generate plain text if "patch" is present, otherwise generate ** "pretty" HTML. ** ** Additional parameters: ** ** verbose Show more detail when describing artifacts ** dc=N Show N lines of context around each diff ** w Ignore whitespace */ void diff_page(void){ int v1, v2; int isPatch; int sideBySide; char *zV1; char *zV2; const char *zRe; const char *zW; /* URL param for ignoring whitespace */ ReCompiled *pRe = 0; u64 diffFlags; u32 objdescFlags = 0; login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } v1 = name_to_rid_www("v1"); v2 = name_to_rid_www("v2"); if( v1==0 || v2==0 ) fossil_redirect_home(); zRe = P("regex"); if( zRe ) re_compile(&pRe, zRe, 0); if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL; isPatch = P("patch")!=0; if( isPatch ){ Blob c1, c2, *pOut; pOut = cgi_output_blob(); cgi_set_content_type("text/plain"); diffFlags = 4; content_get(v1, &c1); content_get(v2, &c2); text_diff(&c1, &c2, pOut, pRe, diffFlags); blob_reset(&c1); blob_reset(&c2); return; } sideBySide = !is_false(PD("sbs","1")); zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1); zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2); diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML; style_header("Diff"); zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; if( *zW ){ style_submenu_element("Show Whitespace Changes", "%s/fdiff?v1=%T&v2=%T&sbs=%d", g.zTop, P("v1"), P("v2"), sideBySide); }else{ style_submenu_element("Ignore Whitespace", "%s/fdiff?v1=%T&v2=%T&sbs=%d&w", g.zTop, P("v1"), P("v2"), sideBySide); } style_submenu_element("Patch", "%s/fdiff?v1=%T&v2=%T&patch", g.zTop, P("v1"), P("v2")); if( !sideBySide ){ style_submenu_element("Side-by-Side Diff", "%s/fdiff?v1=%T&v2=%T&sbs=1%s", g.zTop, P("v1"), P("v2"), zW); }else{ style_submenu_element("Unified Diff", "%s/fdiff?v1=%T&v2=%T&sbs=0%s", g.zTop, P("v1"), P("v2"), zW); } 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 ................................................................................ void rawartifact_page(void){ int rid = 0; char *zUuid; const char *zMime; Blob content; if( P("ci") && P("filename") ){ rid = artifact_from_ci_and_filename(0); } if( rid==0 ){ rid = name_to_rid_www("name"); } login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } if( rid==0 ) fossil_redirect_home(); ................................................................................ /* ** Look for "ci" and "filename" query parameters. If found, try to ** use them to extract the record ID of an artifact for the file. ** ** Also look for "fn" as an alias for "filename". If either "filename" ** or "fn" is present but "ci" is missing, use "tip" as a default value ** for "ci". */ int artifact_from_ci_and_filename(HQuery *pUrl){ const char *zFilename; const char *zCI; int cirid; Manifest *pManifest; ManifestFile *pFile; zFilename = P("filename"); if( zFilename==0 ){ zFilename = P("fn"); if( zFilename==0 ) return 0; } zCI = P("ci"); cirid = name_to_typed_rid(zCI ? zCI : "tip", "ci"); if( cirid<=0 ) return 0; pManifest = manifest_get(cirid, CFTYPE_MANIFEST, 0); if( pManifest==0 ) return 0; manifest_file_rewind(pManifest); while( (pFile = manifest_file_next(pManifest,0))!=0 ){ if( fossil_strcmp(zFilename, pFile->zName)==0 ){ int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid); manifest_destroy(pManifest); if( pUrl ){ url_add_parameter(pUrl, "fn", zFilename); if( zCI ) url_add_parameter(pUrl, "ci", zCI); } return rid; } } manifest_destroy(pManifest); ................................................................................ int descOnly = fossil_strcmp(g.zPath,"whatis")==0; int isFile = fossil_strcmp(g.zPath,"file")==0; const char *zLn = P("ln"); const char *zName = P("name"); HQuery url; url_initialize(&url, g.zPath); rid = artifact_from_ci_and_filename(&url); if( rid==0 ){ url_add_parameter(&url, "name", zName); if( isFile ){ /* Do a top-level directory listing in /file mode if no argument ** specified */ if( zName==0 || zName[0]==0 ){ if( P("ci")==0 ) cgi_set_query_parameter("ci","tip"); ................................................................................ if( (objType & (OBJTYPE_WIKI|OBJTYPE_TICKET))!=0 ){ style_submenu_element("Parsed", "%R/info/%s", zUuid); } if( descOnly ){ style_submenu_element("Content", "%R/artifact/%s", zUuid); }else{ if( zLn==0 || atoi(zLn)==0 ){ style_submenu_checkbox("ln", "Line Numbers", 0); } @ <hr /> content_get(rid, &content); if( renderAsWiki ){ wiki_render_by_mimetype(&content, zMime); }else if( renderAsHtml ){ @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)" |
> > > | | | < < < < < < | < < < < | > > | > | | | | | > > > > > > > > > > | < | | | > < > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < | | | < < < < < < < < < < < < < < < < | > > > > > > > > | > > > | | | > > | | > | | |
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 .... 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 .... 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 .... 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 .... 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 .... 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 .... 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 .... 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 .... 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 .... 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 .... 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 |
@ </td></tr> @ <tr><th>Other Links:</th> @ <td> @ %z(href("%R/tree?ci=%!S",zUuid))files</a> @ | %z(href("%R/fileage?name=%!S",zUuid))file ages</a> @ | %z(href("%R/tree?nofiles&type=tree&ci=%!S",zUuid))folders</a> @ | %z(href("%R/artifact/%!S",zUuid))manifest</a> if( g.perm.Admin ){ @ | %z(href("%R/mlink?ci=%!S",zUuid))mlink table</a> } if( g.anon.Write ){ @ | %z(href("%R/ci_edit?r=%!S",zUuid))edit</a> } @ </td> @ </tr> blob_reset(&projName); } ................................................................................ ** from=TAG Left side of the comparison ** to=TAG Right side of the comparison ** branch=TAG Show all changes on a particular branch ** v=BOOLEAN Default true. If false, only list files that have changed ** sbs=BOOLEAN Side-by-side diff if true. Unified diff if false ** glob=STRING only diff files matching this glob ** dc=N show N lines of context around each diff ** w=BOOLEAN ignore whitespace when computing diffs ** nohdr omit the description at the top of the page ** ** ** Show all differences between two check-ins. */ void vdiff_page(void){ int ridFrom, ridTo; int verboseFlag; int sideBySide; u64 diffFlags = 0; Manifest *pFrom, *pTo; ManifestFile *pFileFrom, *pFileTo; const char *zBranch; const char *zFrom; const char *zTo; const char *zRe; ................................................................................ style_submenu_element("Clear glob", "%R/vdiff?from=%T&to=%T&sbs=%d%s%s", zFrom, zTo, sideBySide, (verboseFlag && !sideBySide)?"&v":"", zW); }else{ style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo, zW); } if( sideBySide || verboseFlag ){ style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); } style_header("Check-in Differences"); if( P("nohdr")==0 ){ @ <h2>Difference From:</h2><blockquote> checkin_description(ridFrom); @ </blockquote><h2>To:</h2><blockquote> checkin_description(ridTo); ................................................................................ db_prepare(&q, "SELECT filename.name, datetime(event.mtime,toLocal())," " coalesce(event.ecomment,event.comment)," " coalesce(event.euser,event.user)," " b.uuid, mlink.mperm," " coalesce((SELECT value FROM tagxref" " WHERE tagid=%d AND tagtype>0 AND rid=mlink.mid),'trunk')," " a.size" " FROM mlink, filename, event, blob a, blob b" " WHERE filename.fnid=mlink.fnid" " AND event.objid=mlink.mid" " AND a.rid=mlink.fid" " AND b.rid=mlink.mid" " AND mlink.fid=%d" " ORDER BY filename.name, event.mtime /*sort*/", ................................................................................ const char *zName = db_column_text(&q, 0); const char *zDate = db_column_text(&q, 1); const char *zCom = db_column_text(&q, 2); const char *zUser = db_column_text(&q, 3); const char *zVers = db_column_text(&q, 4); int mPerm = db_column_int(&q, 5); const char *zBr = db_column_text(&q, 6); int szFile = db_column_int(&q,7); int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0; if( sameFilename && !showDetail ){ if( cnt==1 ){ @ %z(href("%R/whatis/%!S",zUuid))[more...]</a> } cnt++; continue; ................................................................................ @ at hyperlink_to_date(zDate,""); } if( zBr && zBr[0] ){ @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a> } @ — %!W(zCom) (user: hyperlink_to_user(zUser,zDate,","); @ size: %d(szFile)) if( g.perm.Hyperlink ){ @ %z(href("%R/finfo?name=%T&ci=%!S",zName,zVers))[ancestry]</a> @ %z(href("%R/annotate?filename=%T&checkin=%!S",zName,zVers)) @ [annotate]</a> @ %z(href("%R/blame?filename=%T&checkin=%!S",zName,zVers)) @ [blame]</a> } ................................................................................ } return objType; } /* ** WEBPAGE: fdiff ** URL: fdiff?v1=UUID&v2=UUID ** ** Two arguments, v1 and v2, identify the artifacts to be diffed. ** Show diff side by side unless sbs is 0. Generate plain text if ** "patch" is present, otherwise generate "pretty" HTML. ** ** Alternative URL: fdiff?from=filename1&to=filename2&ci=checkin ** ** If the "from" and "to" query parameters are both present, then they are ** the names of two files within the check-in "ci" that are diffed. If the ** "ci" parameter is omitted, then the most recent check-in ("tip") is ** used. ** ** Additional parameters: ** ** dc=N Show N lines of context around each diff ** patch Use the patch diff format ** regex=REGEX Only show differences that match REGEX ** sbs=BOOLEAN Turn side-by-side diffs on and off (default: on) ** verbose=BOOLEAN Show more detail when describing artifacts ** w=BOOLEAN Ignore whitespace */ void diff_page(void){ int v1, v2; int isPatch = P("patch")!=0; int sideBySide = PB("sbs"); int verbose = PB("verbose"); char *zV1; char *zV2; const char *zRe; ReCompiled *pRe = 0; u64 diffFlags; u32 objdescFlags = 0; login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } if( P("from") && P("to") ){ v1 = artifact_from_ci_and_filename(0, "from"); v2 = artifact_from_ci_and_filename(0, "to"); }else{ Stmt q; v1 = name_to_rid_www("v1"); v2 = name_to_rid_www("v2"); /* If the two file versions being compared both have the same ** filename, then offer an "Annotate" link that constructs an ** annotation between those version. */ db_prepare(&q, "SELECT (SELECT substr(uuid,1,20) FROM blob WHERE rid=a.mid)," " (SELECT substr(uuid,1,20) FROM blob WHERE rid=b.mid)," " (SELECT name FROM filename WHERE filename.fnid=a.fnid)" " FROM mlink a, event ea, mlink b, event eb" " WHERE a.fid=%d" " AND b.fid=%d" " AND a.fnid=b.fnid" " AND a.fid!=a.pid" " AND b.fid!=b.pid" " AND ea.objid=a.mid" " AND eb.objid=b.mid" " ORDER BY ea.mtime ASC, eb.mtime ASC", v1, v2 ); if( db_step(&q)==SQLITE_ROW ){ const char *zCkin = db_column_text(&q, 0); const char *zOrig = db_column_text(&q, 1); const char *zFN = db_column_text(&q, 2); style_submenu_element("Annotate", "%R/annotate?origin=%s&checkin=%s&filename=%T", zOrig, zCkin, zFN); } db_finalize(&q); } if( v1==0 || v2==0 ) fossil_redirect_home(); zRe = P("regex"); if( zRe ) re_compile(&pRe, zRe, 0); if( verbose ) objdescFlags |= OBJDESC_DETAIL; if( isPatch ){ Blob c1, c2, *pOut; pOut = cgi_output_blob(); cgi_set_content_type("text/plain"); diffFlags = 4; content_get(v1, &c1); content_get(v2, &c2); text_diff(&c1, &c2, pOut, pRe, diffFlags); blob_reset(&c1); blob_reset(&c2); return; } zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1); zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2); diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML; style_header("Diff"); style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); style_submenu_checkbox("sbs", "Side-by-Side Diff", 0, 0); style_submenu_checkbox("verbose", "Verbose", 0, 0); style_submenu_element("Patch", "%s/fdiff?v1=%T&v2=%T&patch", 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 ................................................................................ void rawartifact_page(void){ int rid = 0; char *zUuid; const char *zMime; Blob content; if( P("ci") && P("filename") ){ rid = artifact_from_ci_and_filename(0, 0); } if( rid==0 ){ rid = name_to_rid_www("name"); } login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } if( rid==0 ) fossil_redirect_home(); ................................................................................ /* ** Look for "ci" and "filename" query parameters. If found, try to ** use them to extract the record ID of an artifact for the file. ** ** Also look for "fn" as an alias for "filename". If either "filename" ** or "fn" is present but "ci" is missing, use "tip" as a default value ** for "ci". ** ** If zNameParam is not NULL, this use that parameter as the filename ** rather than "fn" or "filename". ** ** If pUrl is not NULL, then record the "ci" and "filename" values in ** pUrl. ** ** At least one of pUrl or zNameParam must be NULL. */ int artifact_from_ci_and_filename(HQuery *pUrl, const char *zNameParam){ const char *zFilename; const char *zCI; int cirid; Manifest *pManifest; ManifestFile *pFile; if( zNameParam ){ zFilename = P(zNameParam); }else{ zFilename = P("filename"); if( zFilename==0 ){ zFilename = P("fn"); } } if( zFilename==0 ) return 0; zCI = P("ci"); cirid = name_to_typed_rid(zCI ? zCI : "tip", "ci"); if( cirid<=0 ) return 0; pManifest = manifest_get(cirid, CFTYPE_MANIFEST, 0); if( pManifest==0 ) return 0; manifest_file_rewind(pManifest); while( (pFile = manifest_file_next(pManifest,0))!=0 ){ if( fossil_strcmp(zFilename, pFile->zName)==0 ){ int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid); manifest_destroy(pManifest); if( pUrl ){ assert( zNameParam==0 ); url_add_parameter(pUrl, "fn", zFilename); if( zCI ) url_add_parameter(pUrl, "ci", zCI); } return rid; } } manifest_destroy(pManifest); ................................................................................ int descOnly = fossil_strcmp(g.zPath,"whatis")==0; int isFile = fossil_strcmp(g.zPath,"file")==0; const char *zLn = P("ln"); const char *zName = P("name"); HQuery url; url_initialize(&url, g.zPath); rid = artifact_from_ci_and_filename(&url, 0); if( rid==0 ){ url_add_parameter(&url, "name", zName); if( isFile ){ /* Do a top-level directory listing in /file mode if no argument ** specified */ if( zName==0 || zName[0]==0 ){ if( P("ci")==0 ) cgi_set_query_parameter("ci","tip"); ................................................................................ if( (objType & (OBJTYPE_WIKI|OBJTYPE_TICKET))!=0 ){ style_submenu_element("Parsed", "%R/info/%s", zUuid); } if( descOnly ){ style_submenu_element("Content", "%R/artifact/%s", zUuid); }else{ if( zLn==0 || atoi(zLn)==0 ){ style_submenu_checkbox("ln", "Line Numbers", 0, 0); } @ <hr /> content_get(rid, &content); if( renderAsWiki ){ wiki_render_by_mimetype(&content, zMime); }else if( renderAsHtml ){ @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)" |
Changes to src/json.c.
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 |
VAL(capabilities, json_cap_value());
INT(g, argc);
INT(g, isConst);
CSTR(g, zConfigDbName);
INT(g, repositoryOpen);
INT(g, localOpen);
INT(g, minPrefix);
INT(g, fNoDirSymlinks);
INT(g, fSqlTrace);
INT(g, fSqlStats);
INT(g, fSqlPrint);
INT(g, fQuiet);
INT(g, fHttpTrace);
INT(g, fSystemTrace);
INT(g, fNoSync);
|
< |
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
VAL(capabilities, json_cap_value()); INT(g, argc); INT(g, isConst); CSTR(g, zConfigDbName); INT(g, repositoryOpen); INT(g, localOpen); INT(g, minPrefix); INT(g, fSqlTrace); INT(g, fSqlStats); INT(g, fSqlPrint); INT(g, fQuiet); INT(g, fHttpTrace); INT(g, fSystemTrace); INT(g, fNoSync); |
Changes to src/json_branch.c.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
}
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
fossil_fatal("%s", g.zErrMsg);
}
assert( blob_is_reset(&branch) );
content_deltify(rootid, brid, 0);
if( zNewRid ){
*zNewRid = brid;
}
/* Commit */
db_end_transaction(0);
|
| |
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
}
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
fossil_fatal("%s", g.zErrMsg);
}
assert( blob_is_reset(&branch) );
content_deltify(rootid, &brid, 1, 0);
if( zNewRid ){
*zNewRid = brid;
}
/* Commit */
db_end_transaction(0);
|
Changes to src/main.c.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 ... 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 ... 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 ... 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 .... 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 .... 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 .... 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 |
char *zRepositoryName; /* Name of the repository database file */ char *zLocalDbName; /* Name of the local database file */ char *zOpenRevision; /* Check-in version to use during database open */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int eHashPolicy; /* Current hash policy. One of HPOLICY_* */ int fNoDirSymlinks; /* True if --no-dir-symlinks flag is present */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fJail; /* True if running with a chroot jail */ int fHttpTrace; /* Trace outbound HTTP requests */ int fAnyTrace; /* Any kind of tracing */ ................................................................................ "another flag and is treated as such. --args FILENAME may be used\n" "in conjunction with any other flags.\n"); fossil_exit(1); }else{ const char *zChdir = find_option("chdir",0,1); g.isHTTP = 0; g.rcvid = 0; g.fNoDirSymlinks = find_option("no-dir-symlinks", 0, 0)!=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; g.fSshTrace = find_option("sshtrace", 0, 0)!=0; g.fSshClient = 0; g.zSshCmd = 0; ................................................................................ atexit( fossil_atexit ); #ifdef FOSSIL_ENABLE_TH1_HOOKS /* ** The TH1 return codes from the hook will be handled as follows: ** ** TH_OK: The xFunc() and the TH1 notification will both be executed. ** ** TH_ERROR: The xFunc() will be executed, the TH1 notification will be ** skipped. If the xFunc() is being hooked, the error message ** will be emitted. ** ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. ** ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be ** skipped. ................................................................................ #if defined(FOSSIL_HAVE_FUSEFS) blob_appendf(pOut, "libfuse %s, loaded %s\n", fusefs_inc_version(), fusefs_lib_version()); #endif #if defined(FOSSIL_DEBUG) blob_append(pOut, "FOSSIL_DEBUG\n", -1); #endif #if defined(FOSSIL_OMIT_DELTA_CKSUM_TEST) blob_append(pOut, "FOSSIL_OMIT_DELTA_CKSUM_TEST\n", -1); #endif #if defined(FOSSIL_ENABLE_LEGACY_MV_RM) blob_append(pOut, "FOSSIL_ENABLE_LEGACY_MV_RM\n", -1); #endif #if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) blob_append(pOut, "FOSSIL_ENABLE_EXEC_REL_PATHS\n", -1); #endif ................................................................................ if( nName<7 ) continue; zUrl = sqlite3_mprintf("%.*s", nName-7, zName); if( sqlite3_strglob("*.fossil", zName)!=0 ){ /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands ** do not work for repositories whose names do not end in ".fossil". ** So do not hyperlink those cases. */ @ <li>%h(zName)</li> } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){ @ <li><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a></li> }else{ @ <li><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a></li> } sqlite3_free(zUrl); } ................................................................................ } #endif } /* Locate the method specified by the path and execute the function ** that implements that method. */ if( dispatch_name_search(g.zPath-1, CMDFLAG_WEBPAGE, &pCmd) ){ #ifdef FOSSIL_ENABLE_JSON if(g.json.isJsonMode){ json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); }else #endif { #ifdef FOSSIL_ENABLE_TH1_HOOKS ................................................................................ }else{ #ifdef FOSSIL_ENABLE_TH1_HOOKS /* ** The TH1 return codes from the hook will be handled as follows: ** ** TH_OK: The xFunc() and the TH1 notification will both be executed. ** ** TH_ERROR: The xFunc() will be executed, the TH1 notification will be ** skipped. If the xFunc() is being hooked, the error message ** will be emitted. ** ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. ** ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be ** skipped. |
< < | | | > > > | > > | |
139 140 141 142 143 144 145 146 147 148 149 150 151 152 ... 619 620 621 622 623 624 625 626 627 628 629 630 631 632 ... 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 ... 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 .... 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 .... 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 .... 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 |
char *zRepositoryName; /* Name of the repository database file */ char *zLocalDbName; /* Name of the local database file */ char *zOpenRevision; /* Check-in version to use during database open */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int eHashPolicy; /* Current hash policy. One of HPOLICY_* */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fJail; /* True if running with a chroot jail */ int fHttpTrace; /* Trace outbound HTTP requests */ int fAnyTrace; /* Any kind of tracing */ ................................................................................ "another flag and is treated as such. --args FILENAME may be used\n" "in conjunction with any other flags.\n"); fossil_exit(1); }else{ const char *zChdir = find_option("chdir",0,1); g.isHTTP = 0; g.rcvid = 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; g.fSshTrace = find_option("sshtrace", 0, 0)!=0; g.fSshClient = 0; g.zSshCmd = 0; ................................................................................ atexit( fossil_atexit ); #ifdef FOSSIL_ENABLE_TH1_HOOKS /* ** The TH1 return codes from the hook will be handled as follows: ** ** TH_OK: The xFunc() and the TH1 notification will both be executed. ** ** TH_ERROR: The xFunc() will be skipped, the TH1 notification will be ** skipped. If the xFunc() is being hooked, the error message ** will be emitted. ** ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. ** ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be ** skipped. ................................................................................ #if defined(FOSSIL_HAVE_FUSEFS) blob_appendf(pOut, "libfuse %s, loaded %s\n", fusefs_inc_version(), fusefs_lib_version()); #endif #if defined(FOSSIL_DEBUG) blob_append(pOut, "FOSSIL_DEBUG\n", -1); #endif #if defined(FOSSIL_ENABLE_DELTA_CKSUM_TEST) blob_append(pOut, "FOSSIL_ENABLE_DELTA_CKSUM_TEST\n", -1); #endif #if defined(FOSSIL_ENABLE_LEGACY_MV_RM) blob_append(pOut, "FOSSIL_ENABLE_LEGACY_MV_RM\n", -1); #endif #if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) blob_append(pOut, "FOSSIL_ENABLE_EXEC_REL_PATHS\n", -1); #endif ................................................................................ if( nName<7 ) continue; zUrl = sqlite3_mprintf("%.*s", nName-7, zName); if( sqlite3_strglob("*.fossil", zName)!=0 ){ /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands ** do not work for repositories whose names do not end in ".fossil". ** So do not hyperlink those cases. */ @ <li>%h(zName)</li> } else if( sqlite3_strglob("*/.*", zName)==0 ){ /* Do not show hidden repos */ @ <li>%h(zName) (hidden)</li> } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){ @ <li><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a></li> }else{ @ <li><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a></li> } sqlite3_free(zUrl); } ................................................................................ } #endif } /* Locate the method specified by the path and execute the function ** that implements that method. */ if( dispatch_name_search(g.zPath-1, CMDFLAG_WEBPAGE, &pCmd) && dispatch_alias(g.zPath-1, &pCmd) ){ #ifdef FOSSIL_ENABLE_JSON if(g.json.isJsonMode){ json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); }else #endif { #ifdef FOSSIL_ENABLE_TH1_HOOKS ................................................................................ }else{ #ifdef FOSSIL_ENABLE_TH1_HOOKS /* ** The TH1 return codes from the hook will be handled as follows: ** ** TH_OK: The xFunc() and the TH1 notification will both be executed. ** ** TH_ERROR: The xFunc() will be skipped, the TH1 notification will be ** skipped. If the xFunc() is being hooked, the error message ** will be emitted. ** ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. ** ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be ** skipped. |
Changes to src/main.mk.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
$(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ |
| > |
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
$(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md \ $(SRCDIR)/wiki.wiki TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ |
Changes to src/makemake.tcl.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 ... 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 .... 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 |
} # Additional resource files that get built into the executable. # set extra_files { diff.tcl markdown.md ../skins/*/*.txt } # Options used to compile the included SQLite library. # set SQLITE_OPTIONS { -DNDEBUG=1 ................................................................................ endif #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.0f OPENSSLINCDIR = $(OPENSSLDIR)/include OPENSSLLIBDIR = $(OPENSSLDIR) #### 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 ................................................................................ # Enable support for the SQLite Encryption Extension? !ifndef USE_SEE USE_SEE = 0 !endif !if $(FOSSIL_ENABLE_SSL)!=0 SSLDIR = $(B)\compat\openssl-1.1.0f SSLINCDIR = $(SSLDIR)\inc32 !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLLIBDIR = $(SSLDIR)\out32dll !else SSLLIBDIR = $(SSLDIR)\out32 !endif SSLLFLAGS = /nologo /opt:ref /debug |
> | | |
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 ... 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 .... 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 |
} # Additional resource files that get built into the executable. # set extra_files { diff.tcl markdown.md wiki.wiki ../skins/*/*.txt } # Options used to compile the included SQLite library. # set SQLITE_OPTIONS { -DNDEBUG=1 ................................................................................ endif #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.0g OPENSSLINCDIR = $(OPENSSLDIR)/include OPENSSLLIBDIR = $(OPENSSLDIR) #### 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 ................................................................................ # Enable support for the SQLite Encryption Extension? !ifndef USE_SEE USE_SEE = 0 !endif !if $(FOSSIL_ENABLE_SSL)!=0 SSLDIR = $(B)\compat\openssl-1.1.0g SSLINCDIR = $(SSLDIR)\inc32 !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLLIBDIR = $(SSLDIR)\out32dll !else SSLLIBDIR = $(SSLDIR)\out32 !endif SSLLFLAGS = /nologo /opt:ref /debug |
Changes to src/manifest.c.
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 .... 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 .... 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 .... 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 |
db_bind_int(&s1, ":n", fnid); db_bind_int(&s1, ":pfn", pfnid); db_bind_int(&s1, ":mp", mperm); db_bind_int(&s1, ":isaux", isPrimary==0); db_exec(&s1); } if( pid && fid ){ content_deltify(pid, fid, 0); } } /* ** Do a binary search to find a file in the p->aFile[] array. ** ** As an optimization, guess that the file we seek is at index p->iFile. ................................................................................ } /* Try to make the parent manifest a delta from the child, if that ** is an appropriate thing to do. For a new baseline, make the ** previous baseline a delta from the current baseline. */ if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ content_deltify(pmid, mid, 0); }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ content_deltify(pParent->pBaseline->rid, mid, 0); } /* Remember all children less than a few seconds younger than their parent, ** as we might want to fudge the times for those children. */ if( pChild->rDate<pParent->rDate+AGE_FUDGE_WINDOW && manifest_crosslink_busy ................................................................................ prior = db_int(0, "SELECT rid FROM tagxref" " WHERE tagid=%d AND mtime<%.17g" " ORDER BY mtime DESC", tagid, p->rDate ); if( prior ){ content_deltify(prior, rid, 0); } if( nWiki>0 ){ zComment = mprintf("Changes to wiki page [%h]", p->zWikiTitle); }else{ zComment = mprintf("Deleted wiki page [%h]", p->zWikiTitle); } search_doc_touch('w',rid,p->zWikiTitle); ................................................................................ subsequent = db_int(0, "SELECT rid FROM tagxref" " WHERE tagid=%d AND mtime>=%.17g AND rid!=%d" " ORDER BY mtime", tagid, p->rDate, rid ); if( prior ){ content_deltify(prior, rid, 0); if( !subsequent ){ db_multi_exec( "DELETE FROM event" " WHERE type='e'" " AND tagid=%d" " AND objid IN (SELECT rid FROM tagxref WHERE tagid=%d)", tagid, tagid ); } } if( subsequent ){ content_deltify(rid, subsequent, 0); }else{ search_doc_touch('e',rid,0); db_multi_exec( "REPLACE INTO event(type,mtime,objid,tagid,user,comment,bgcolor)" "VALUES('e',%.17g,%d,%d,%Q,%Q," " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));", p->rEventDate, rid, tagid, p->zUser, p->zComment, |
| | | | | | |
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 .... 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 .... 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 .... 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 |
db_bind_int(&s1, ":n", fnid); db_bind_int(&s1, ":pfn", pfnid); db_bind_int(&s1, ":mp", mperm); db_bind_int(&s1, ":isaux", isPrimary==0); db_exec(&s1); } if( pid && fid ){ content_deltify(pid, &fid, 1, 0); } } /* ** Do a binary search to find a file in the p->aFile[] array. ** ** As an optimization, guess that the file we seek is at index p->iFile. ................................................................................ } /* Try to make the parent manifest a delta from the child, if that ** is an appropriate thing to do. For a new baseline, make the ** previous baseline a delta from the current baseline. */ if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ content_deltify(pmid, &mid, 1, 0); }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ content_deltify(pParent->pBaseline->rid, &mid, 1, 0); } /* Remember all children less than a few seconds younger than their parent, ** as we might want to fudge the times for those children. */ if( pChild->rDate<pParent->rDate+AGE_FUDGE_WINDOW && manifest_crosslink_busy ................................................................................ prior = db_int(0, "SELECT rid FROM tagxref" " WHERE tagid=%d AND mtime<%.17g" " ORDER BY mtime DESC", tagid, p->rDate ); if( prior ){ content_deltify(prior, &rid, 1, 0); } if( nWiki>0 ){ zComment = mprintf("Changes to wiki page [%h]", p->zWikiTitle); }else{ zComment = mprintf("Deleted wiki page [%h]", p->zWikiTitle); } search_doc_touch('w',rid,p->zWikiTitle); ................................................................................ subsequent = db_int(0, "SELECT rid FROM tagxref" " WHERE tagid=%d AND mtime>=%.17g AND rid!=%d" " ORDER BY mtime", tagid, p->rDate, rid ); if( prior ){ content_deltify(prior, &rid, 1, 0); if( !subsequent ){ db_multi_exec( "DELETE FROM event" " WHERE type='e'" " AND tagid=%d" " AND objid IN (SELECT rid FROM tagxref WHERE tagid=%d)", tagid, tagid ); } } if( subsequent ){ content_deltify(rid, &subsequent, 1, 0); }else{ search_doc_touch('e',rid,0); db_multi_exec( "REPLACE INTO event(type,mtime,objid,tagid,user,comment,bgcolor)" "VALUES('e',%.17g,%d,%d,%Q,%Q," " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));", p->rEventDate, rid, tagid, p->zUser, p->zComment, |
Changes to src/markdown.md.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
|
# Markdown Overview # ## Paragraphs ## > Paragraphs are divided by blank lines. > End a line with two or more spaces to force a mid-paragraph line break. ## Headings ## > # Top-level Heading Alternative Top Level Heading # Top-level Heading Variant # ============================= > ## Second-level Heading Alternative 2nd Level Heading ## Second-level Heading Variant ## ----------------------------- ## Links ## > 1. **\[display text\]\(URL\)** > 2. **\[display text\]\(URL "Title"\)** > 3. **\[display text\]\(URL 'Title'\)** > 4. **\<URL\>** ................................................................................ > This paragraph is indented > > > > Double-indented paragraph > Begin each line with at least four spaces or one tab to produce a verbatim > code block. ## Miscellaneous ## > * In-line images are made using **\!\[alt-text\]\(image-URL\)**. > * Use HTML for complex formatting such as tables and forms. > * Escape special characters (ex: "\[", "\(", "\*") > using backslash (ex: "\\\[", "\\\(", "\\\*"). > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal > rule. Spaces and extra **-**/**\***/**_** are allowed. > * See [daringfireball.net][] for additional information. > * See this page's [Markdown source](/md_rules?txt=1) for more examples. ## Special Features For Fossil ## > * In hyperlinks, if the URL begins with "/" then the root of the Fossil > repository is prepended. This allows for repository-relative hyperlinks. > * For documents that begin with a top-level heading (ex: "# heading #"), the > heading is omitted from the body of the document and becomes the document > title displayed at the top of the Fossil page. [daringfireball.net]: http://daringfireball.net/projects/markdown/syntax |
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<
>
>
|
|
|
|
|
|
|
|
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
..
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
|
# Markdown Overview # ## Paragraphs ## > Paragraphs are divided by blank lines. > End a line with two or more spaces to force a mid-paragraph line break. ## Headings ## > # Top Level Heading Alternative Top Level Heading # Top Level Heading Variant # ============================= > ## 2nd Level Heading Alternative 2nd Level Heading ## 2nd Level Heading Variant ## ----------------------------- > ### 3rd Level Heading ### 3rd Level Heading Variant ### #### 4th Level Heading #### 4th Level Heading Variant #### ##### 5th Level Heading ##### 5th Level Heading Variant ##### ###### 6th Level Heading ###### 6th Level Heading Variant ###### ## Links ## > 1. **\[display text\]\(URL\)** > 2. **\[display text\]\(URL "Title"\)** > 3. **\[display text\]\(URL 'Title'\)** > 4. **\<URL\>** ................................................................................ > This paragraph is indented > > > > Double-indented paragraph > Begin each line with at least four spaces or one tab to produce a verbatim > code block. ## Tables ## > | Header 1 | Header 2 | Header 3 | ---------------------------------------------- | Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 | |:Left-aligned |:Centered :| Right-aligned:| | | ← Blank → | | | Row 4 Col 1 | Row 4 Col 2 | Row 4 Col 3 | > The first row is a header if followed by a horizontal rule or a blank line. > Placing **:** at the left, both, or right sides of a cell gives left-aligned, > centered, or right-aligned text, respectively. By default, header cells are > centered, and body cells are left-aligned. > The leftmost **\|** is required if the first column contains at least one > blank cell. The rightmost **\|** is optional. ## Miscellaneous ## > * In-line images are made using **\!\[alt-text\]\(image-URL\)**. > * Use HTML for advanced formatting such as forms. > * **\<!--** HTML-style comments **-->** are supported. > * Escape special characters (ex: **\[** **\(** **\|** **\***) > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***). > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal > rule. Spaces and extra **-**/**\***/**_** are allowed. > * See [daringfireball.net][] for additional information. > * See this page's [Markdown source](/md_rules?txt=1) for complex examples. ## Special Features For Fossil ## > * In hyperlinks, if the URL begins with **/** then the root of the Fossil > repository is prepended. This allows for repository-relative hyperlinks. > * For documents that begin with a top-level heading (ex: **# heading #**), > the heading is omitted from the body of the document and becomes the > document title displayed at the top of the Fossil page. [daringfireball.net]: http://daringfireball.net/projects/markdown/syntax |
Changes to src/markdown_html.c.
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
html_escape(ob, blob_buffer(link), blob_size(link)); } BLOB_APPEND_LITERAL(ob, "</a>"); return 1; } static int html_code_span(struct Blob *ob, struct Blob *text, void *opaque){ BLOB_APPEND_LITERAL(ob, "<code>"); html_escape(ob, blob_buffer(text), blob_size(text)); BLOB_APPEND_LITERAL(ob, "</code>"); return 1; } static int html_double_emphasis( struct Blob *ob, struct Blob *text, char c, |
> | | | > |
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
html_escape(ob, blob_buffer(link), blob_size(link)); } BLOB_APPEND_LITERAL(ob, "</a>"); return 1; } static int html_code_span(struct Blob *ob, struct Blob *text, void *opaque){ if( text ){ BLOB_APPEND_LITERAL(ob, "<code>"); html_escape(ob, blob_buffer(text), blob_size(text)); BLOB_APPEND_LITERAL(ob, "</code>"); } return 1; } static int html_double_emphasis( struct Blob *ob, struct Blob *text, char c, |
Changes to src/merge.c.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
** ** -f|--force Force the merge even if it would be a no-op. ** ** --force-missing Force the merge even if there is missing content. ** ** --integrate Merged branch will be closed when committing. ** ** --no-dir-symlinks Disables support for directory symlinks. ** ** -n|--dry-run If given, display instead of run actions ** ** -v|--verbose Show additional details of the merge */ void merge_cmd(void){ int vid; /* Current version "V" */ int mid; /* Version we are merging from "M" */ |
< < |
204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
** ** -f|--force Force the merge even if it would be a no-op. ** ** --force-missing Force the merge even if there is missing content. ** ** --integrate Merged branch will be closed when committing. ** ** -n|--dry-run If given, display instead of run actions ** ** -v|--verbose Show additional details of the merge */ void merge_cmd(void){ int vid; /* Current version "V" */ int mid; /* Version we are merging from "M" */ |
Changes to src/mkbuiltin.c.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
******************************************************************************* ** ** This is a stand-alone utility program that is part of the Fossil build ** process. This program reads files named on the command line and converts ** them into ANSI-C static char array variables. Output is written onto ** standard output. ** ** The makefiles use this utility package various resources (large scripts, ** GIF images, etc) that are separate files in the source code as byte ** arrays in the resulting executable. */ #include <stdio.h> #include <stdlib.h> #include <string.h> |
| |
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
*******************************************************************************
**
** This is a stand-alone utility program that is part of the Fossil build
** process. This program reads files named on the command line and converts
** them into ANSI-C static char array variables. Output is written onto
** standard output.
**
** The makefiles use this utility to package various resources (large scripts,
** GIF images, etc) that are separate files in the source code as byte
** arrays in the resulting executable.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
|
Changes to src/mkindex.c.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 .. 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 ... 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 ... 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 ... 339 340 341 342 343 344 345 346 347 348 349 350 351 352 ... 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 ... 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This program scans Fossil source code files looking for special ** comments that indicate a command-line command or a webpage. This ** routine collects information about these entry points and then ** generates (on standard output) C code used by Fossil to dispatch ** to those entry points. ** ** The source code is scanned for comment lines of the form: ** ** WEBPAGE: /abc/xyz ** COMMAND: cmdname ** ** These comment should be followed by a function definition of the ** form: ** ** void function_name(void){ ** ** This routine creates C source code for a constant table that maps ** command and webpage name into pointers to the function. ** ** Command names can divided into three classes: 1st-tier, 2nd-tier, ** and test. 1st-tier commands are the most frequently used and the ** ones that show up with "fossil help". 2nd-tier are seldom-used and/or ** legacy command. Test commands are unsupported commands used for testing ** and analysis only. ** ** Commands are 1st-tier by default. If the command name begins with ................................................................................ ** a test command. If the command name has a "2nd-tier" argument or ends ** with a "*" character, it is second tier. Examples: ** ** COMMAND: abcde* ** COMMAND: fghij 2nd-tier ** COMMAND: test-xyzzy ** COMMAND: xyzzy test ** ** New arguments may be added in future releases that set additional ** bits in the eCmdFlags field. ** ** Additional lines of comment after the COMMAND: or WEBPAGE: become ** the built-in help text for that command or webpage. ** ** Multiple COMMAND: entries can be attached to the same command, thus ** creating multiple aliases for that command. Similarly, multiple ** WEBPAGE: entries can be attached to the same webpage function, to give ** that page aliases. */ #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <string.h> /*************************************************************************** ** These macros must match similar macros in dispatch.c. ** ** Allowed values for CmdOrPage.eCmdFlags. */ #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */ #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */ #define CMDFLAG_TEST 0x0004 /* Commands for testing only */ #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */ #define CMDFLAG_COMMAND 0x0010 /* A command */ /**************************************************************************/ /* ** Each entry looks like this: */ typedef struct Entry { int eType; /* CMDFLAG_* values */ char *zIf; /* Enclose in #if */ char *zFunc; /* Name of implementation */ char *zPath; /* Webpage or command name */ char *zHelp; /* Help text */ int iHelp; /* Index of Help text */ } Entry; /* ** Maximum number of entries */ #define N_ENTRY 5000 ................................................................................ aEntry[nUsed].eType |= CMDFLAG_1ST_TIER; }else if( j==8 && strncmp(&zLine[i], "2nd-tier", j)==0 ){ aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_TEST); aEntry[nUsed].eType |= CMDFLAG_2ND_TIER; }else if( j==4 && strncmp(&zLine[i], "test", j)==0 ){ aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_2ND_TIER); aEntry[nUsed].eType |= CMDFLAG_TEST; }else{ fprintf(stderr, "%s:%d: unknown option: '%.*s'\n", zFile, nLine, j, &zLine[i]); nErr++; } } nUsed++; } /* ** Check to see if the current line is an #if and if it is, add it to ** the zIf[] string. If the current line is an #endif or #else or #elif ** then cancel the current zIf[] string. */ ................................................................................ if( strncmp(&zLine[i],"if",2)==0 ){ zIf[0] = '#'; memcpy(&zIf[1], &zLine[i], len+1); }else if( zLine[i]=='e' ){ zIf[0] = 0; } } /* ** Scan a line for a function that implements a web page or command. */ void scan_for_func(char *zLine){ int i,j,k; char *z; if( nUsed<=nFixed ) return; if( strncmp(zLine, "**", 2)==0 && fossil_isspace(zLine[2]) && strlen(zLine)<sizeof(zHelp)-nHelp-1 && nUsed>nFixed && strncmp(zLine,"** COMMAND:",11)!=0 && strncmp(zLine,"** WEBPAGE:",11)!=0 ){ if( zLine[2]=='\n' ){ zHelp[nHelp++] = '\n'; }else{ if( strncmp(&zLine[3], "Usage: ", 6)==0 ) nHelp = 0; strcpy(&zHelp[nHelp], &zLine[3]); nHelp += strlen(&zHelp[nHelp]); } return; } for(i=0; fossil_isspace(zLine[i]); i++){} if( zLine[i]==0 ) return; if( strncmp(&zLine[i],"void",4)!=0 ){ if( zLine[i]!='*' ) goto page_skip; return; } i += 4; if( !fossil_isspace(zLine[i]) ) goto page_skip; while( fossil_isspace(zLine[i]) ){ i++; } for(j=0; fossil_isident(zLine[i+j]); j++){} if( j==0 ) goto page_skip; for(k=nHelp-1; k>=0 && fossil_isspace(zHelp[k]); k--){} nHelp = k+1; zHelp[nHelp] = 0; for(k=0; k<nHelp && fossil_isspace(zHelp[k]); k++){} if( k<nHelp ){ z = string_dup(&zHelp[k], nHelp-k); }else{ z = ""; } for(k=nFixed; k<nUsed; k++){ aEntry[k].zIf = zIf[0] ? string_dup(zIf, -1) : 0; aEntry[k].zFunc = string_dup(&zLine[i], j); aEntry[k].zHelp = z; z = 0; aEntry[k].iHelp = nFixed; } i+=j; while( fossil_isspace(zLine[i]) ){ i++; } if( zLine[i]!='(' ) goto page_skip; nFixed = nUsed; nHelp = 0; return; page_skip: for(i=nFixed; i<nUsed; i++){ fprintf(stderr,"%s:%d: skipping page \"%s\"\n", ................................................................................ "** This file was generated by the mkindex.exe program based on\n" "** comments in other Fossil source files.\n" "*/\n" ); /* Output declarations for all the action functions */ for(i=0; i<nFixed; i++){ if( aEntry[i].zIf ) printf("%s", aEntry[i].zIf); printf("extern void %s(void);\n", aEntry[i].zFunc); if( aEntry[i].zIf ) printf("#endif\n"); } /* Output strings for all the help text */ for(i=0; i<nFixed; i++){ ................................................................................ const char *z = aEntry[i].zPath; int n = strlen(z); if( aEntry[i].zIf ){ printf("%s", aEntry[i].zIf); }else if( (aEntry[i].eType & CMDFLAG_WEBPAGE)!=0 ){ nWeb++; } printf(" { \"%.*s\",%*s%s,%*szHelp%03d, 0x%02x },\n", n, z, 25-n, "", aEntry[i].zFunc, (int)(30-strlen(aEntry[i].zFunc)), "", aEntry[i].iHelp, aEntry[i].eType ); if( aEntry[i].zIf ) printf("#endif\n"); } printf("};\n"); printf("#define FOSSIL_FIRST_CMD %d\n", nWeb); } /* ** Process a single file of input */ void process_file(void){ FILE *in = fopen(zFile, "r"); ................................................................................ nLine = 0; while( fgets(zLine, sizeof(zLine), in) ){ nLine++; scan_for_if(zLine); scan_for_label("WEBPAGE:",zLine,CMDFLAG_WEBPAGE); scan_for_label("COMMAND:",zLine,CMDFLAG_COMMAND); scan_for_func(zLine); } fclose(in); nUsed = nFixed; } int main(int argc, char **argv){ int i; |
| | | < < > | < > < < < > > > > > > | | > > > > > > > > > > | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | > | > | | | > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 .. 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 ... 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 ... 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 ... 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 ... 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 ... 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This utility program scans Fossil source text looking for specially ** formatted comments and generates C source code for constant tables ** that define the behavior of commands, webpages, and settings. ** ** The source code is scanned for comment lines of the form: ** ** WEBPAGE: /abc/xyz ** COMMAND: cmdname ** SETTING: access-log ** ** The WEBPAGE and COMMAND comments should be followed by a function that ** implements the webpage or command. The form of this function is: ** ** void function_name(void){ ** ** Command names can divided into three classes: 1st-tier, 2nd-tier, ** and test. 1st-tier commands are the most frequently used and the ** ones that show up with "fossil help". 2nd-tier are seldom-used and/or ** legacy command. Test commands are unsupported commands used for testing ** and analysis only. ** ** Commands are 1st-tier by default. If the command name begins with ................................................................................ ** a test command. If the command name has a "2nd-tier" argument or ends ** with a "*" character, it is second tier. Examples: ** ** COMMAND: abcde* ** COMMAND: fghij 2nd-tier ** COMMAND: test-xyzzy ** COMMAND: xyzzy test ** ** A SETTING: may be followed by arguments that give additional attributes ** to that setting: ** ** SETTING: clean-blob versionable width=40 block-text ** SETTING: auto-shun boolean default=on ** ** New arguments may be added in future releases that set additional ** bits in the eCmdFlags field. ** ** Additional lines of comment after the COMMAND: or WEBPAGE: or SETTING: ** become the built-in help text for that command or webpage or setting. ** ** Multiple COMMAND: entries can be attached to the same command, thus ** creating multiple aliases for that command. Similarly, multiple ** WEBPAGE: entries can be attached to the same webpage function, to give ** that page aliases. ** ** For SETTING: entries, the default value for the setting can be specified ** using a default=VALUE argument if the default contains no spaces. If the ** default value does contain spaces, use a separate line like this: ** ** SETTING: pgp-command ** DEFAULT: gpg --clearsign -o ** ** If no default is supplied, the default is assumed to be an empty string ** or "off" in the case of a boolean. */ #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <string.h> /*************************************************************************** ** These macros must match similar macros in dispatch.c. ** ** Allowed values for CmdOrPage.eCmdFlags. */ #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */ #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */ #define CMDFLAG_TEST 0x0004 /* Commands for testing only */ #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */ #define CMDFLAG_COMMAND 0x0010 /* A command */ #define CMDFLAG_SETTING 0x0020 /* A setting */ #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */ #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */ #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */ /**************************************************************************/ /* ** Each entry looks like this: */ typedef struct Entry { int eType; /* CMDFLAG_* values */ char *zIf; /* Enclose in #if */ char *zFunc; /* Name of implementation */ char *zPath; /* Webpage or command name */ char *zHelp; /* Help text */ char *zDflt; /* Default value for settings */ char *zVar; /* config.name for settings, if different from zPath */ int iHelp; /* Index of Help text */ int iWidth; /* Display width for SETTING: values */ } Entry; /* ** Maximum number of entries */ #define N_ENTRY 5000 ................................................................................ aEntry[nUsed].eType |= CMDFLAG_1ST_TIER; }else if( j==8 && strncmp(&zLine[i], "2nd-tier", j)==0 ){ aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_TEST); aEntry[nUsed].eType |= CMDFLAG_2ND_TIER; }else if( j==4 && strncmp(&zLine[i], "test", j)==0 ){ aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_2ND_TIER); aEntry[nUsed].eType |= CMDFLAG_TEST; }else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){ aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT); aEntry[nUsed].iWidth = 0; aEntry[nUsed].eType |= CMDFLAG_BOOLEAN; }else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){ aEntry[nUsed].eType &= ~(CMDFLAG_BOOLEAN); aEntry[nUsed].eType |= CMDFLAG_BLOCKTEXT; }else if( j==11 && strncmp(&zLine[i], "versionable", j)==0 ){ aEntry[nUsed].eType |= CMDFLAG_VERSIONABLE; }else if( j>6 && strncmp(&zLine[i], "width=", 6)==0 ){ aEntry[nUsed].iWidth = atoi(&zLine[i+6]); }else if( j>8 && strncmp(&zLine[i], "default=", 8)==0 ){ aEntry[nUsed].zDflt = string_dup(&zLine[i+8], j-8); }else if( j>9 && strncmp(&zLine[i], "variable=", 9)==0 ){ aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9); }else{ fprintf(stderr, "%s:%d: unknown option: '%.*s'\n", zFile, nLine, j, &zLine[i]); nErr++; } } nUsed++; return; } /* ** Check to see if the current line is an #if and if it is, add it to ** the zIf[] string. If the current line is an #endif or #else or #elif ** then cancel the current zIf[] string. */ ................................................................................ if( strncmp(&zLine[i],"if",2)==0 ){ zIf[0] = '#'; memcpy(&zIf[1], &zLine[i], len+1); }else if( zLine[i]=='e' ){ zIf[0] = 0; } } /* ** Check to see if the current line is a "** DEFAULT: ..." line for a ** SETTING definition. If so, remember the default value. */ void scan_for_default(const char *zLine){ int len; const char *z; if( nUsed<1 ) return; if( (aEntry[nUsed-1].eType & CMDFLAG_SETTING)==0 ) return; if( strncmp(zLine, "** DEFAULT: ", 12)!=0 ) return; z = zLine + 12; while( fossil_isspace(z[0]) ) z++; len = (int)strlen(z); while( len>0 && fossil_isspace(z[len-1]) ){ len--; } aEntry[nUsed-1].zDflt = string_dup(z,len); } /* ** Scan a line for a function that implements a web page or command. */ void scan_for_func(char *zLine){ int i,j,k; char *z; int isSetting; if( nUsed<=nFixed ) return; if( strncmp(zLine, "**", 2)==0 && fossil_isspace(zLine[2]) && strlen(zLine)<sizeof(zHelp)-nHelp-1 && nUsed>nFixed && strncmp(zLine,"** COMMAND:",11)!=0 && strncmp(zLine,"** WEBPAGE:",11)!=0 && strncmp(zLine,"** SETTING:",11)!=0 && strncmp(zLine,"** DEFAULT:",11)!=0 ){ if( zLine[2]=='\n' ){ zHelp[nHelp++] = '\n'; }else{ if( strncmp(&zLine[3], "Usage: ", 6)==0 ) nHelp = 0; strcpy(&zHelp[nHelp], &zLine[3]); nHelp += strlen(&zHelp[nHelp]); } return; } for(i=0; fossil_isspace(zLine[i]); i++){} if( zLine[i]==0 ) return; isSetting = (aEntry[nFixed].eType & CMDFLAG_SETTING)!=0; if( !isSetting ){ if( strncmp(&zLine[i],"void",4)!=0 ){ if( zLine[i]!='*' ) goto page_skip; return; } i += 4; if( !fossil_isspace(zLine[i]) ) goto page_skip; while( fossil_isspace(zLine[i]) ){ i++; } for(j=0; fossil_isident(zLine[i+j]); j++){} if( j==0 ) goto page_skip; } for(k=nHelp-1; k>=0 && fossil_isspace(zHelp[k]); k--){} nHelp = k+1; zHelp[nHelp] = 0; for(k=0; k<nHelp && fossil_isspace(zHelp[k]); k++){} if( k<nHelp ){ z = string_dup(&zHelp[k], nHelp-k); }else{ z = ""; } for(k=nFixed; k<nUsed; k++){ aEntry[k].zIf = zIf[0] ? string_dup(zIf, -1) : 0; aEntry[k].zFunc = isSetting ? "0" : string_dup(&zLine[i], j); aEntry[k].zHelp = z; z = 0; aEntry[k].iHelp = nFixed; } if( !isSetting ){ i+=j; while( fossil_isspace(zLine[i]) ){ i++; } if( zLine[i]!='(' ) goto page_skip; } nFixed = nUsed; nHelp = 0; return; page_skip: for(i=nFixed; i<nUsed; i++){ fprintf(stderr,"%s:%d: skipping page \"%s\"\n", ................................................................................ "** This file was generated by the mkindex.exe program based on\n" "** comments in other Fossil source files.\n" "*/\n" ); /* Output declarations for all the action functions */ for(i=0; i<nFixed; i++){ if( aEntry[i].eType & CMDFLAG_SETTING ) continue; if( aEntry[i].zIf ) printf("%s", aEntry[i].zIf); printf("extern void %s(void);\n", aEntry[i].zFunc); if( aEntry[i].zIf ) printf("#endif\n"); } /* Output strings for all the help text */ for(i=0; i<nFixed; i++){ ................................................................................ const char *z = aEntry[i].zPath; int n = strlen(z); if( aEntry[i].zIf ){ printf("%s", aEntry[i].zIf); }else if( (aEntry[i].eType & CMDFLAG_WEBPAGE)!=0 ){ nWeb++; } printf(" { \"%.*s\",%*s%s,%*szHelp%03d, 0x%03x },\n", n, z, 25-n, "", aEntry[i].zFunc, (int)(29-strlen(aEntry[i].zFunc)), "", aEntry[i].iHelp, aEntry[i].eType ); if( aEntry[i].zIf ) printf("#endif\n"); } printf("};\n"); printf("#define FOSSIL_FIRST_CMD %d\n", nWeb); /* Generate the aSetting[] table */ printf("const Setting aSetting[] = {\n"); for(i=0; i<nFixed; i++){ const char *z; const char *zVar; const char *zDef; if( (aEntry[i].eType & CMDFLAG_SETTING)==0 ) continue; z = aEntry[i].zPath; zVar = aEntry[i].zVar; zDef = aEntry[i].zDflt; if( zDef==0 ) zDef = ""; if( aEntry[i].zIf ){ printf("%s", aEntry[i].zIf); } printf(" { \"%s\",%*s", z, (int)(20-strlen(z)), ""); if( zVar ){ printf(" \"%s\",%*s", zVar, (int)(15-strlen(zVar)), ""); }else{ printf(" 0,%*s", 16, ""); } printf(" %3d, %d, %d, \"%s\"%*s },\n", aEntry[i].iWidth, (aEntry[i].eType & CMDFLAG_VERSIONABLE)!=0, (aEntry[i].eType & CMDFLAG_BLOCKTEXT)!=0, zDef, (int)(10-strlen(zDef)), "" ); if( aEntry[i].zIf ){ printf("#endif\n"); } } printf("{0,0,0,0,0,0}};\n"); } /* ** Process a single file of input */ void process_file(void){ FILE *in = fopen(zFile, "r"); ................................................................................ nLine = 0; while( fgets(zLine, sizeof(zLine), in) ){ nLine++; scan_for_if(zLine); scan_for_label("WEBPAGE:",zLine,CMDFLAG_WEBPAGE); scan_for_label("COMMAND:",zLine,CMDFLAG_COMMAND); scan_for_func(zLine); scan_for_label("SETTING:",zLine,CMDFLAG_SETTING); scan_for_default(zLine); } fclose(in); nUsed = nFixed; } int main(int argc, char **argv){ int i; |
Changes to src/mkversion.c.
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 |
** ./a.out manifest.uuid manifest VERSION ** ** Note that the manifest.uuid and manifest files are generated by Fossil. */ #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char *argv[]){ FILE *m,*u,*v; char *z; #if defined(__DMC__) /* e.g. 0x857 */ int i = 0; #endif int j = 0, x = 0, d = 0; int vn[3]; char b[1000]; char vx[1000]; memset(b,0,sizeof(b)); memset(vx,0,sizeof(vx)); u = fopen(argv[1],"r"); if( fgets(b, sizeof(b)-1,u)==0 ){ fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]); exit(1); } fclose(u); for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} *z = 0; printf("#define MANIFEST_UUID \"%s\"\n",b); printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); m = fopen(argv[2],"r"); while(b == fgets(b, sizeof(b)-1,m)){ if(0 == strncmp("D ",b,2)){ printf("#define MANIFEST_DATE \"%.10s %.8s\"\n",b+2,b+13); printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2); } } fclose(m); v = fopen(argv[3],"r"); if( fgets(b, sizeof(b)-1,v)==0 ){ fprintf(stderr, "malformed VERSION file: %s\n", argv[3]); exit(1); } fclose(v); for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} *z = 0; |
> > > > > > > > > > > > > < > | | |
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 |
** ./a.out manifest.uuid manifest VERSION ** ** Note that the manifest.uuid and manifest files are generated by Fossil. */ #include <stdio.h> #include <string.h> #include <stdlib.h> static FILE *open_for_reading(const char *zFilename){ FILE *f = fopen(zFilename, "r"); if( f==0 ){ fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename); exit(1); } return f; } int main(int argc, char *argv[]){ FILE *m,*u,*v; char *z; #if defined(__DMC__) /* e.g. 0x857 */ int i = 0; #endif int j = 0, x = 0, d = 0; int vn[3]; char b[1000]; char vx[1000]; if( argc!=4 ){ fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]); exit(1); } memset(b,0,sizeof(b)); memset(vx,0,sizeof(vx)); u = open_for_reading(argv[1]); if( fgets(b, sizeof(b)-1,u)==0 ){ fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]); exit(1); } fclose(u); for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} *z = 0; printf("#define MANIFEST_UUID \"%s\"\n",b); printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); m = open_for_reading(argv[2]); while(b == fgets(b, sizeof(b)-1,m)){ if(0 == strncmp("D ",b,2)){ printf("#define MANIFEST_DATE \"%.10s %.8s\"\n",b+2,b+13); printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2); } } fclose(m); v = open_for_reading(argv[3]); if( fgets(b, sizeof(b)-1,v)==0 ){ fprintf(stderr, "malformed VERSION file: %s\n", argv[3]); exit(1); } fclose(v); for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} *z = 0; |
Changes to src/name.c.
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
....
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
|
char *zSha1Bg;
char *zSha3Bg;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("List Of Artifacts");
style_submenu_element("250 Largest", "bigbloblist");
if( !unpubOnly && mx>n && P("s")==0 ){
int i;
@ <p>Select a range of artifacts to view:</p>
@ <ul>
for(i=1; i<=mx; i+=n){
@ <li> %z(href("%R/bloblist?s=%d&n=%d",i,n))
@ %d(i)..%d(i+n-1<mx?i+n-1:mx)</a>
................................................................................
*/
void bigbloblist_page(void){
Stmt q;
int n = atoi(PD("n","250"));
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("%d Largest Artifacts", n);
db_multi_exec(
"CREATE TEMP TABLE toshow(rid INTEGER PRIMARY KEY);"
"INSERT INTO toshow(rid)"
" SELECT rid FROM blob"
" ORDER BY length(content) DESC"
" LIMIT %d;", n
|
>
>
>
>
>
>
>
|
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
....
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
|
char *zSha1Bg; char *zSha3Bg; login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } style_header("List Of Artifacts"); style_submenu_element("250 Largest", "bigbloblist"); if( g.perm.Admin ){ style_submenu_element("Artifact Log", "rcvfromlist"); } if( !unpubOnly && mx>n && P("s")==0 ){ int i; @ <p>Select a range of artifacts to view:</p> @ <ul> for(i=1; i<=mx; i+=n){ @ <li> %z(href("%R/bloblist?s=%d&n=%d",i,n)) @ %d(i)..%d(i+n-1<mx?i+n-1:mx)</a> ................................................................................ */ void bigbloblist_page(void){ Stmt q; int n = atoi(PD("n","250")); login_check_credentials(); if( !g.perm.Read ){ login_needed(g.anon.Read); return; } if( g.perm.Admin ){ style_submenu_element("Artifact Log", "rcvfromlist"); } style_submenu_element("All Artifacts", "bloblist"); style_header("%d Largest Artifacts", n); db_multi_exec( "CREATE TEMP TABLE toshow(rid INTEGER PRIMARY KEY);" "INSERT INTO toshow(rid)" " SELECT rid FROM blob" " ORDER BY length(content) DESC" " LIMIT %d;", n |
Changes to src/path.c.
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
*/ static struct { PathNode *pCurrent; /* Current generation of nodes */ PathNode *pAll; /* All nodes */ Bag seen; /* Nodes seen before */ int nStep; /* Number of steps from first to last */ PathNode *pStart; /* Earliest node */ PathNode *pPivot; /* Common ancestor of pStart and pEnd */ PathNode *pEnd; /* Most recent */ } path; /* ** Return the first (last) element of the computed path. */ PathNode *path_first(void){ return path.pStart; } ................................................................................ PathNode *path_midpoint(void){ PathNode *p; int i; if( path.nStep<2 ) return 0; for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){} return p; } /* ** COMMAND: test-shortest-path ** ** Usage: %fossil test-shortest-path ?--no-merge? VERSION1 VERSION2 ** ** Report the shortest path between two check-ins. If the --no-merge flag |
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
*/ static struct { PathNode *pCurrent; /* Current generation of nodes */ PathNode *pAll; /* All nodes */ Bag seen; /* Nodes seen before */ int nStep; /* Number of steps from first to last */ PathNode *pStart; /* Earliest node */ PathNode *pEnd; /* Most recent */ } path; /* ** Return the first (last) element of the computed path. */ PathNode *path_first(void){ return path.pStart; } ................................................................................ PathNode *path_midpoint(void){ PathNode *p; int i; if( path.nStep<2 ) return 0; for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){} return p; } /* ** Compute the shortest path between two check-ins and then transfer ** that path into the "ancestor" table. This is a utility used by ** both /annotate and /finfo. See also: compute_direct_ancestors(). */ void path_shortest_stored_in_ancestor_table( int origid, /* RID for check-in at start of the path */ int cid /* RID for check-in at the end of the path */ ){ PathNode *pPath; int gen = 0; Stmt ins; pPath = path_shortest(cid, origid, 1, 0); db_multi_exec( "CREATE TEMP TABLE IF NOT EXISTS ancestor(" " rid INT UNIQUE," " generation INTEGER PRIMARY KEY" ");" "DELETE FROM ancestor;" ); db_prepare(&ins, "INSERT INTO ancestor(rid, generation) VALUES(:rid,:gen)"); while( pPath ){ db_bind_int(&ins, ":rid", pPath->rid); db_bind_int(&ins, ":gen", ++gen); db_step(&ins); db_reset(&ins); pPath = pPath->u.pTo; } db_finalize(&ins); path_reset(); } /* ** COMMAND: test-shortest-path ** ** Usage: %fossil test-shortest-path ?--no-merge? VERSION1 VERSION2 ** ** Report the shortest path between two check-ins. If the --no-merge flag |
Changes to src/pivot.c.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
** ** Options: ** --ignore-merges Ignore merges for discovering name pivots */ void test_find_pivot(void){ int i, rid; int ignoreMerges = find_option("ignore-merges",0,0)!=0; if( g.argc<4 ){ usage("?options? PRIMARY SECONDARY ..."); } db_must_be_within_tree(); pivot_set_primary(name_to_rid(g.argv[2])); for(i=3; i<g.argc; i++){ pivot_set_secondary(name_to_rid(g.argv[i])); } rid = pivot_find(ignoreMerges); printf("pivot=%s\n", db_text("?","SELECT uuid FROM blob WHERE rid=%d",rid) ); } |
> > > > > > > > > > > > > > > > | > > > |
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 |
** ** Options: ** --ignore-merges Ignore merges for discovering name pivots */ void test_find_pivot(void){ int i, rid; int ignoreMerges = find_option("ignore-merges",0,0)!=0; int showDetails = find_option("details",0,0)!=0; if( g.argc<4 ){ usage("?options? PRIMARY SECONDARY ..."); } db_must_be_within_tree(); pivot_set_primary(name_to_rid(g.argv[2])); for(i=3; i<g.argc; i++){ pivot_set_secondary(name_to_rid(g.argv[i])); } rid = pivot_find(ignoreMerges); printf("pivot=%s\n", db_text("?","SELECT uuid FROM blob WHERE rid=%d",rid) ); if( showDetails ){ Stmt q; db_prepare(&q, "SELECT substr(uuid,1,12), aqueue.rid, datetime(aqueue.mtime)," " aqueue.pending, aqueue.src\n" " FROM aqueue JOIN blob ON aqueue.rid=blob.rid\n" " ORDER BY aqueue.mtime DESC" ); while( db_step(&q)==SQLITE_ROW ){ printf("\"%s\",%d,\"%s\",%d,%d\n", db_column_text(&q, 0), db_column_int(&q, 1), db_column_text(&q, 2), db_column_int(&q, 3), db_column_int(&q, 4)); } db_finalize(&q); } } |
Changes to src/printf.c.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
if( nDigitHuman > 40 ) nDigitHuman = 40; nDigitUrl = nDigitHuman + 6; if( nDigitUrl < FOSSIL_HASH_DIGITS_URL ) nDigitUrl = FOSSIL_HASH_DIGITS_URL; if( nDigitUrl > 40 ) nDigitUrl = 40; } return bForUrl ? nDigitUrl : nDigitHuman; } /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ #define etFLOAT 2 /* Floating point. %f */ |
> > > > > > > |
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
if( nDigitHuman > 40 ) nDigitHuman = 40; nDigitUrl = nDigitHuman + 6; if( nDigitUrl < FOSSIL_HASH_DIGITS_URL ) nDigitUrl = FOSSIL_HASH_DIGITS_URL; if( nDigitUrl > 40 ) nDigitUrl = 40; } return bForUrl ? nDigitUrl : nDigitHuman; } /* ** Return the number of characters in a %S output. */ int length_of_S_display(void){ return hashDigits(0); } /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ #define etFLOAT 2 /* Floating point. %f */ |
Changes to src/rebuild.c.
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
if(!g.fQuiet && ttyOutput ){ percent_complete(1000); fossil_print("\n"); } return errCnt; } /* ** Attempt to convert more full-text blobs into delta-blobs for ** storage efficiency. */ void extra_deltification(void){ Stmt q; int topid, previd, rid; int prevfnid, fnid; db_begin_transaction(); db_prepare(&q, "SELECT rid FROM event, blob" " WHERE blob.rid=event.objid" " AND event.type='ci'" " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)" " ORDER BY event.mtime DESC" ); topid = previd = 0; while( db_step(&q)==SQLITE_ROW ){ rid = db_column_int(&q, 0); if( topid==0 ){ topid = previd = rid; }else{ if( content_deltify(rid, previd, 0)==0 && previd!=topid ){ content_deltify(rid, topid, 0); } previd = rid; } } db_finalize(&q); db_prepare(&q, "SELECT blob.rid, mlink.fnid FROM blob, mlink, plink" " WHERE NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)" " AND mlink.fid=blob.rid" " AND mlink.mid=plink.cid" " AND plink.cid=mlink.mid" " ORDER BY mlink.fnid, plink.mtime DESC" ); prevfnid = 0; while( db_step(&q)==SQLITE_ROW ){ rid = db_column_int(&q, 0); fnid = db_column_int(&q, 1); if( prevfnid!=fnid ){ prevfnid = fnid; topid = previd = rid; }else{ if( content_deltify(rid, previd, 0)==0 && previd!=topid ){ content_deltify(rid, topid, 0); } previd = rid; } } db_finalize(&q); db_end_transaction(0); } |
> > > > > | > > > > > > | | < < < | | > | > > > > > > > > | | | | < < | | > | > > > > |
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 |
if(!g.fQuiet && ttyOutput ){ percent_complete(1000); fossil_print("\n"); } return errCnt; } /* ** Number of neighbors to search */ #define N_NEIGHBOR 5 /* ** Attempt to convert more full-text blobs into delta-blobs for ** storage efficiency. */ void extra_deltification(void){ Stmt q; int aPrev[N_NEIGHBOR]; int nPrev; int rid; int prevfnid, fnid; db_begin_transaction(); /* Look for manifests that have not been deltaed and try to make them ** children of one of the 5 chronologically subsequent check-ins */ db_prepare(&q, "SELECT rid FROM event, blob" " WHERE blob.rid=event.objid" " AND event.type='ci'" " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)" " ORDER BY event.mtime DESC" ); nPrev = 0; while( db_step(&q)==SQLITE_ROW ){ rid = db_column_int(&q, 0); if( nPrev>0 ){ content_deltify(rid, aPrev, nPrev, 0); } if( nPrev<N_NEIGHBOR ){ aPrev[nPrev++] = rid; }else{ int i; for(i=0; i<N_NEIGHBOR-1; i++) aPrev[i] = aPrev[i+1]; aPrev[N_NEIGHBOR-1] = rid; } } db_finalize(&q); /* For individual files that have not been deltaed, try to find ** a parent which is an undeltaed file with the same name in a ** more recent branch. */ db_prepare(&q, "SELECT DISTINCT blob.rid, mlink.fnid FROM blob, mlink, plink" " WHERE NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)" " AND mlink.fid=blob.rid" " AND mlink.mid=plink.cid" " AND plink.cid=mlink.mid" " ORDER BY mlink.fnid, plink.mtime DESC" ); prevfnid = 0; while( db_step(&q)==SQLITE_ROW ){ rid = db_column_int(&q, 0); fnid = db_column_int(&q, 1); if( fnid!=prevfnid ) nPrev = 0; prevfnid = fnid; if( nPrev>0 ){ content_deltify(rid, aPrev, nPrev, 0); } if( nPrev<N_NEIGHBOR ){ aPrev[nPrev++] = rid; }else{ int i; for(i=0; i<N_NEIGHBOR-1; i++) aPrev[i] = aPrev[i+1]; aPrev[N_NEIGHBOR-1] = rid; } } db_finalize(&q); db_end_transaction(0); } |
Changes to src/search.c.
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 ... 768 769 770 771 772 773 774 775 776 777 778 779 780 781 ... 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 .... 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 .... 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 .... 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 .... 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 .... 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 .... 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 .... 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 .... 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 .... 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 .... 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 .... 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 .... 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 .... 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 |
blob_reset(&sql); print_timeline(&q, nLimit, width, 0); db_finalize(&q); } #if INTERFACE /* What to search for */ #define SRCH_CKIN 0x0001 /* Search over check-in comments */ #define SRCH_DOC 0x0002 /* Search over embedded documents */ #define SRCH_TKT 0x0004 /* Search over tickets */ #define SRCH_WIKI 0x0008 /* Search over wiki */ #define SRCH_ALL 0x000f /* Search over everything */ #endif /* ** Remove bits from srchFlags which are disallowed by either the ** current server configuration or by user permissions. */ unsigned int search_restrict(unsigned int srchFlags){ static unsigned int knownGood = 0; static unsigned int knownBad = 0; static const struct { unsigned m; const char *zKey; } aSetng[] = { { SRCH_CKIN, "search-ci" }, { SRCH_DOC, "search-doc" }, { SRCH_TKT, "search-tkt" }, { SRCH_WIKI, "search-wiki" }, }; int i; if( g.perm.Read==0 ) srchFlags &= ~(SRCH_CKIN|SRCH_DOC); if( g.perm.RdTkt==0 ) srchFlags &= ~(SRCH_TKT); if( g.perm.RdWiki==0 ) srchFlags &= ~(SRCH_WIKI); for(i=0; i<count(aSetng); i++){ unsigned int m = aSetng[i].m; if( (srchFlags & m)==0 ) continue; if( ((knownGood|knownBad) & m)!=0 ) continue; if( db_get_boolean(aSetng[i].zKey,0) ){ ................................................................................ " search_score()," " 't'||tkt_id," " datetime(tkt_mtime)," " search_snippet()" " FROM ticket" " WHERE search_match(title('t',tkt_id,NULL),body('t',tkt_id,NULL));" ); } } /* ** Number of significant bits in a u32 */ static int nbits(u32 x){ ................................................................................ " WHERE ftsidx MATCH %Q" " AND ftsdocs.rowid=ftsidx.docid", zPattern ); if( srchFlags!=SRCH_ALL ){ const char *zSep = " AND ("; static const struct { unsigned m; char c; } aMask[] = { { SRCH_CKIN, 'c' }, { SRCH_DOC, 'd' }, { SRCH_TKT, 't' }, { SRCH_WIKI, 'w' }, }; int i; for(i=0; i<count(aMask); i++){ if( srchFlags & aMask[i].m ){ blob_appendf(&sql, "%sftsdocs.type='%c'", zSep, aMask[i].c); zSep = " OR "; } ................................................................................ const char *zClass = 0; const char *zDisable1; const char *zDisable2; const char *zPattern; int fDebug = PB("debug"); srchFlags = search_restrict(srchFlags); switch( srchFlags ){ case SRCH_CKIN: zType = " Check-ins"; zClass = "Ckin"; break; case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break; case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break; case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break; } if( srchFlags==0 ){ zDisable1 = " disabled"; zDisable2 = " disabled"; zPattern = ""; }else{ zDisable1 = " autofocus"; ................................................................................ @ <div class='searchForm searchForm%s(zClass)'> }else{ @ <div class='searchForm'> } @ <input type="text" name="s" size="40" value="%h(zPattern)"%s(zDisable1)> if( useYparam && (srchFlags & (srchFlags-1))!=0 && useYparam ){ static const struct { char *z; char *zNm; unsigned m; } aY[] = { { "all", "All", SRCH_ALL }, { "c", "Check-ins", SRCH_CKIN }, { "d", "Docs", SRCH_DOC }, { "t", "Tickets", SRCH_TKT }, { "w", "Wiki", SRCH_WIKI }, }; const char *zY = PD("y","all"); unsigned newFlags = srchFlags; int i; @ <select size='1' name='y'> for(i=0; i<count(aY); i++){ if( (aY[i].m & srchFlags)==0 ) continue; ................................................................................ ** ** s=PATTERN Specify the full-text pattern to search for ** y=TYPE What to search. ** c -> check-ins ** d -> documentation ** t -> tickets ** w -> wiki ** all -> everything */ void search_page(void){ login_check_credentials(); style_header("Search"); search_screen(SRCH_ALL, 1); style_footer(); ................................................................................ ** Return "search text" - a reduced version of a document appropriate for ** full text search and/or for constructing a search result snippet. ** ** cType: d Embedded documentation ** w Wiki page ** c Check-in comment ** t Ticket text ** ** rid The RID of an artifact that defines the object ** being searched. ** ** zName Name of the object being searched. This is used ** only to help figure out the mimetype (text/plain, ** test/html, test/x-fossil-wiki, or text/x-markdown) ................................................................................ Blob doc; content_get(rid, &doc); blob_to_utf8_no_bom(&doc, 0); get_stext_by_mimetype(&doc, mimetype_from_name(zName), pOut); blob_reset(&doc); break; } case 'w': { /* Wiki */ Manifest *pWiki = manifest_get(rid, CFTYPE_WIKI,0); Blob wiki; if( pWiki==0 ) break; blob_init(&wiki, pWiki->zWiki, -1); get_stext_by_mimetype(&wiki, wiki_filter_mimetypes(pWiki->zMimetype), pOut); blob_reset(&wiki); manifest_destroy(pWiki); ................................................................................ /* ** COMMAND: test-search-stext ** ** Usage: fossil test-search-stext TYPE RID NAME ** ** Compute the search text for document TYPE-RID whose name is NAME. ** The TYPE is one of "c", "d", "t", or "w". The RID is the document ** ID. The NAME is used to figure out a mimetype to use for formatting ** the raw document text. */ void test_search_stext(void){ Blob out; db_find_and_open_repository(0,0); if( g.argc!=5 ) usage("TYPE RID NAME"); ................................................................................ ") INSERT OR IGNORE INTO ftsdocs(type,rid,name,idxed)" " SELECT 'w', rid, name, 0 FROM latest_wiki;" ); db_multi_exec( "INSERT OR IGNORE INTO ftsdocs(type,rid,idxed)" " SELECT 't', tkt_id, 0 FROM ticket;" ); } /* ** The document described by cType,rid,zName is about to be added or ** updated. If the document has already been indexed, then unindex it ** now while we still have access to the old content. Add the document ** to the queue of documents that need to be indexed or reindexed. ................................................................................ zType, rid ); db_multi_exec( "REPLACE INTO ftsdocs(type,rid,name,idxed)" " VALUES(%Q,%d,%Q,0)", zType, rid, zName ); if( cType=='w' ){ db_multi_exec( "DELETE FROM ftsidx WHERE docid IN" " (SELECT rowid FROM ftsdocs WHERE type='w' AND name=%Q AND idxed)", zName ); db_multi_exec( "DELETE FROM ftsdocs WHERE type='w' AND name=%Q AND rid!=%d", zName, rid ); } } } /* ** If the doc-glob and doc-br settings are valid for document search ................................................................................ " 'Wiki: '||ftsdocs.name," " '/wiki?name='||urlencode(ftsdocs.name)," " tagxref.mtime" " FROM tagxref WHERE tagxref.rid=ftsdocs.rid)" " WHERE ftsdocs.type='w' AND NOT ftsdocs.idxed" ); } /* ** Deal with all of the unindexed entries in the FTSDOCS table - that ** is to say, all the entries with FTSDOCS.IDXED=0. Add them to the ** index. */ void search_update_index(unsigned int srchFlags){ ................................................................................ } if( srchFlags & SRCH_TKT ){ search_update_ticket_index(); } if( srchFlags & SRCH_WIKI ){ search_update_wiki_index(); } } /* ** Construct, prepopulate, and then update the full-text index. */ void search_rebuild_index(void){ fossil_print("rebuilding the search index..."); ................................................................................ ** of the repository. Subcommands: ** ** reindex Rebuild the search index. This is a no-op if ** index search is disabled ** ** index (on|off) Turn the search index on or off ** ** enable cdtw Enable various kinds of search. c=Check-ins, ** d=Documents, t=Tickets, w=Wiki. ** ** disable cdtw Disable various kinds of search ** ** stemmer (on|off) Turn the Porter stemmer on or off for indexed ** search. (Unindexed search is never stemmed.) ** ** The current search settings are displayed after any changes are applied. ** Run this command with no arguments to simply see the settings. */ ................................................................................ { 1, "reindex" }, { 2, "index" }, { 3, "disable" }, { 4, "enable" }, { 5, "stemmer" }, }; static const struct { char *zSetting; char *zName; char *zSw; } aSetng[] = { { "search-ckin", "check-in search:", "c" }, { "search-doc", "document search:", "d" }, { "search-tkt", "ticket search:", "t" }, { "search-wiki", "wiki search:", "w" }, }; char *zSubCmd = 0; int i, j, n; int iCmd = 0; int iAction = 0; db_find_and_open_repository(0, 0); if( g.argc>2 ){ ................................................................................ } if( iAction>=2 ){ search_rebuild_index(); } /* Always show the status before ending */ for(i=0; i<count(aSetng); i++){ fossil_print("%-16s %s\n", aSetng[i].zName, db_get_boolean(aSetng[i].zSetting,0) ? "on" : "off"); } fossil_print("%-16s %s\n", "Porter stemmer:", db_get_boolean("search-stemmer",0) ? "on" : "off"); if( search_index_exists() ){ fossil_print("%-16s enabled\n", "full-text index:"); fossil_print("%-16s %d\n", "documents:", db_int(0, "SELECT count(*) FROM ftsdocs")); }else{ fossil_print("%-16s disabled\n", "full-text index:"); } db_end_transaction(0); } /* ** WEBPAGE: test-ftsdocs ** |
| | | | > | | | | | > | > > > > > > > > > > > > > > > > > > > > | | | | > | | | | > | | | | | > > > > | > | > > > > | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | > | | | | | |
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 ... 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 ... 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 .... 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 .... 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 .... 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 .... 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 .... 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 .... 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 .... 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 .... 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 .... 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 .... 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 .... 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 .... 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 .... 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 |
blob_reset(&sql); print_timeline(&q, nLimit, width, 0); db_finalize(&q); } #if INTERFACE /* What to search for */ #define SRCH_CKIN 0x0001 /* Search over check-in comments */ #define SRCH_DOC 0x0002 /* Search over embedded documents */ #define SRCH_TKT 0x0004 /* Search over tickets */ #define SRCH_WIKI 0x0008 /* Search over wiki */ #define SRCH_TECHNOTE 0x0010 /* Search over tech notes */ #define SRCH_ALL 0x001f /* Search over everything */ #endif /* ** Remove bits from srchFlags which are disallowed by either the ** current server configuration or by user permissions. */ unsigned int search_restrict(unsigned int srchFlags){ static unsigned int knownGood = 0; static unsigned int knownBad = 0; static const struct { unsigned m; const char *zKey; } aSetng[] = { { SRCH_CKIN, "search-ci" }, { SRCH_DOC, "search-doc" }, { SRCH_TKT, "search-tkt" }, { SRCH_WIKI, "search-wiki" }, { SRCH_TECHNOTE, "search-technote" }, }; int i; if( g.perm.Read==0 ) srchFlags &= ~(SRCH_CKIN|SRCH_DOC|SRCH_TECHNOTE); if( g.perm.RdTkt==0 ) srchFlags &= ~(SRCH_TKT); if( g.perm.RdWiki==0 ) srchFlags &= ~(SRCH_WIKI); for(i=0; i<count(aSetng); i++){ unsigned int m = aSetng[i].m; if( (srchFlags & m)==0 ) continue; if( ((knownGood|knownBad) & m)!=0 ) continue; if( db_get_boolean(aSetng[i].zKey,0) ){ ................................................................................ " search_score()," " 't'||tkt_id," " datetime(tkt_mtime)," " search_snippet()" " FROM ticket" " WHERE search_match(title('t',tkt_id,NULL),body('t',tkt_id,NULL));" ); } if( (srchFlags & SRCH_TECHNOTE)!=0 ){ db_multi_exec( "WITH technote(uuid,rid,mtime) AS (" " SELECT substr(tagname,7), tagxref.rid, max(tagxref.mtime)" " FROM tag, tagxref" " WHERE tag.tagname GLOB 'event-*'" " AND tagxref.tagid=tag.tagid" " GROUP BY 1" ")" "INSERT INTO x(label,url,score,id,date,snip)" " SELECT printf('Tech Note: %%s',uuid)," " printf('/technote/%%s',uuid)," " search_score()," " 'e'||rid," " datetime(mtime)," " search_snippet()" " FROM technote" " WHERE search_match('',body('e',rid,NULL));" ); } } /* ** Number of significant bits in a u32 */ static int nbits(u32 x){ ................................................................................ " WHERE ftsidx MATCH %Q" " AND ftsdocs.rowid=ftsidx.docid", zPattern ); if( srchFlags!=SRCH_ALL ){ const char *zSep = " AND ("; static const struct { unsigned m; char c; } aMask[] = { { SRCH_CKIN, 'c' }, { SRCH_DOC, 'd' }, { SRCH_TKT, 't' }, { SRCH_WIKI, 'w' }, { SRCH_TECHNOTE, 'e' }, }; int i; for(i=0; i<count(aMask); i++){ if( srchFlags & aMask[i].m ){ blob_appendf(&sql, "%sftsdocs.type='%c'", zSep, aMask[i].c); zSep = " OR "; } ................................................................................ const char *zClass = 0; const char *zDisable1; const char *zDisable2; const char *zPattern; int fDebug = PB("debug"); srchFlags = search_restrict(srchFlags); switch( srchFlags ){ case SRCH_CKIN: zType = " Check-ins"; zClass = "Ckin"; break; case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break; case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break; case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break; case SRCH_TECHNOTE: zType = " Tech Notes"; zClass = "Note"; break; } if( srchFlags==0 ){ zDisable1 = " disabled"; zDisable2 = " disabled"; zPattern = ""; }else{ zDisable1 = " autofocus"; ................................................................................ @ <div class='searchForm searchForm%s(zClass)'> }else{ @ <div class='searchForm'> } @ <input type="text" name="s" size="40" value="%h(zPattern)"%s(zDisable1)> if( useYparam && (srchFlags & (srchFlags-1))!=0 && useYparam ){ static const struct { char *z; char *zNm; unsigned m; } aY[] = { { "all", "All", SRCH_ALL }, { "c", "Check-ins", SRCH_CKIN }, { "d", "Docs", SRCH_DOC }, { "t", "Tickets", SRCH_TKT }, { "w", "Wiki", SRCH_WIKI }, { "e", "Tech Notes", SRCH_TECHNOTE }, }; const char *zY = PD("y","all"); unsigned newFlags = srchFlags; int i; @ <select size='1' name='y'> for(i=0; i<count(aY); i++){ if( (aY[i].m & srchFlags)==0 ) continue; ................................................................................ ** ** s=PATTERN Specify the full-text pattern to search for ** y=TYPE What to search. ** c -> check-ins ** d -> documentation ** t -> tickets ** w -> wiki ** e -> tech notes ** all -> everything */ void search_page(void){ login_check_credentials(); style_header("Search"); search_screen(SRCH_ALL, 1); style_footer(); ................................................................................ ** Return "search text" - a reduced version of a document appropriate for ** full text search and/or for constructing a search result snippet. ** ** cType: d Embedded documentation ** w Wiki page ** c Check-in comment ** t Ticket text ** e Tech note ** ** rid The RID of an artifact that defines the object ** being searched. ** ** zName Name of the object being searched. This is used ** only to help figure out the mimetype (text/plain, ** test/html, test/x-fossil-wiki, or text/x-markdown) ................................................................................ Blob doc; content_get(rid, &doc); blob_to_utf8_no_bom(&doc, 0); get_stext_by_mimetype(&doc, mimetype_from_name(zName), pOut); blob_reset(&doc); break; } case 'e': /* Tech Notes */ case 'w': { /* Wiki */ Manifest *pWiki = manifest_get(rid, cType == 'e' ? CFTYPE_EVENT : CFTYPE_WIKI, 0); Blob wiki; if( pWiki==0 ) break; blob_init(&wiki, pWiki->zWiki, -1); get_stext_by_mimetype(&wiki, wiki_filter_mimetypes(pWiki->zMimetype), pOut); blob_reset(&wiki); manifest_destroy(pWiki); ................................................................................ /* ** COMMAND: test-search-stext ** ** Usage: fossil test-search-stext TYPE RID NAME ** ** Compute the search text for document TYPE-RID whose name is NAME. ** The TYPE is one of "c", "d", "t", "w", or "e". The RID is the document ** ID. The NAME is used to figure out a mimetype to use for formatting ** the raw document text. */ void test_search_stext(void){ Blob out; db_find_and_open_repository(0,0); if( g.argc!=5 ) usage("TYPE RID NAME"); ................................................................................ ") INSERT OR IGNORE INTO ftsdocs(type,rid,name,idxed)" " SELECT 'w', rid, name, 0 FROM latest_wiki;" ); db_multi_exec( "INSERT OR IGNORE INTO ftsdocs(type,rid,idxed)" " SELECT 't', tkt_id, 0 FROM ticket;" ); db_multi_exec( "INSERT OR IGNORE INTO ftsdocs(type,rid,name,idxed)" " SELECT 'e', objid, comment, 0 FROM event WHERE type='e';" ); } /* ** The document described by cType,rid,zName is about to be added or ** updated. If the document has already been indexed, then unindex it ** now while we still have access to the old content. Add the document ** to the queue of documents that need to be indexed or reindexed. ................................................................................ zType, rid ); db_multi_exec( "REPLACE INTO ftsdocs(type,rid,name,idxed)" " VALUES(%Q,%d,%Q,0)", zType, rid, zName ); if( cType=='w' || cType=='e' ){ db_multi_exec( "DELETE FROM ftsidx WHERE docid IN" " (SELECT rowid FROM ftsdocs WHERE type='%c' AND name=%Q AND idxed)", cType, zName ); db_multi_exec( "DELETE FROM ftsdocs WHERE type='%c' AND name=%Q AND rid!=%d", cType, zName, rid ); } } } /* ** If the doc-glob and doc-br settings are valid for document search ................................................................................ " 'Wiki: '||ftsdocs.name," " '/wiki?name='||urlencode(ftsdocs.name)," " tagxref.mtime" " FROM tagxref WHERE tagxref.rid=ftsdocs.rid)" " WHERE ftsdocs.type='w' AND NOT ftsdocs.idxed" ); } /* ** Deal with all of the unindexed 'e' terms in FTSDOCS */ static void search_update_technote_index(void){ db_multi_exec( "INSERT INTO ftsidx(docid,title,body)" " SELECT rowid, title('e',rid,NULL),body('e',rid,NULL) FROM ftsdocs" " WHERE type='e' AND NOT idxed;" ); if( db_changes()==0 ) return; db_multi_exec( "UPDATE ftsdocs SET idxed=1," " (name,label,url,mtime) = " " (SELECT ftsdocs.name," " 'Tech Note: '||ftsdocs.name," " '/technote/'||substr(tag.tagname,7)," " tagxref.mtime" " FROM tagxref, tag USING (tagid)" " WHERE tagxref.rid=ftsdocs.rid" " AND tagname GLOB 'event-*')" " WHERE ftsdocs.type='e' AND NOT ftsdocs.idxed" ); } /* ** Deal with all of the unindexed entries in the FTSDOCS table - that ** is to say, all the entries with FTSDOCS.IDXED=0. Add them to the ** index. */ void search_update_index(unsigned int srchFlags){ ................................................................................ } if( srchFlags & SRCH_TKT ){ search_update_ticket_index(); } if( srchFlags & SRCH_WIKI ){ search_update_wiki_index(); } if( srchFlags & SRCH_TECHNOTE ){ search_update_technote_index(); } } /* ** Construct, prepopulate, and then update the full-text index. */ void search_rebuild_index(void){ fossil_print("rebuilding the search index..."); ................................................................................ ** of the repository. Subcommands: ** ** reindex Rebuild the search index. This is a no-op if ** index search is disabled ** ** index (on|off) Turn the search index on or off ** ** enable cdtwe Enable various kinds of search. c=Check-ins, ** d=Documents, t=Tickets, w=Wiki, e=Tech Notes. ** ** disable cdtwe Disable various kinds of search ** ** stemmer (on|off) Turn the Porter stemmer on or off for indexed ** search. (Unindexed search is never stemmed.) ** ** The current search settings are displayed after any changes are applied. ** Run this command with no arguments to simply see the settings. */ ................................................................................ { 1, "reindex" }, { 2, "index" }, { 3, "disable" }, { 4, "enable" }, { 5, "stemmer" }, }; static const struct { char *zSetting; char *zName; char *zSw; } aSetng[] = { { "search-ckin", "check-in search:", "c" }, { "search-doc", "document search:", "d" }, { "search-tkt", "ticket search:", "t" }, { "search-wiki", "wiki search:", "w" }, { "search-technote", "tech note search:", "e" }, }; char *zSubCmd = 0; int i, j, n; int iCmd = 0; int iAction = 0; db_find_and_open_repository(0, 0); if( g.argc>2 ){ ................................................................................ } if( iAction>=2 ){ search_rebuild_index(); } /* Always show the status before ending */ for(i=0; i<count(aSetng); i++){ fossil_print("%-17s %s\n", aSetng[i].zName, db_get_boolean(aSetng[i].zSetting,0) ? "on" : "off"); } fossil_print("%-17s %s\n", "Porter stemmer:", db_get_boolean("search-stemmer",0) ? "on" : "off"); if( search_index_exists() ){ fossil_print("%-17s enabled\n", "full-text index:"); fossil_print("%-17s %d\n", "documents:", db_int(0, "SELECT count(*) FROM ftsdocs")); }else{ fossil_print("%-17s disabled\n", "full-text index:"); } db_end_transaction(0); } /* ** WEBPAGE: test-ftsdocs ** |
Changes to src/setup.c.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 .... 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 .... 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 .... 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 .... 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 .... 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 .... 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 .... 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 .... 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 .... 2306 2307 2308 2309 2310 2311 2312 |
setup_menu_entry("Login-Group", "setup_login_group", "Manage single sign-on between this repository and others" " on the same server"); setup_menu_entry("Tickets", "tktsetup", "Configure the trouble-ticketing system for this repository"); setup_menu_entry("Search","srchsetup", "Configure the built-in search engine"); setup_menu_entry("Transfers", "xfersetup", "Configure the transfer system for this repository"); setup_menu_entry("Skins", "setup_skin", "Select and/or modify the web interface \"skins\""); setup_menu_entry("Moderation", "setup_modreq", "Enable/Disable requiring moderator approval of Wiki and/or Ticket" " changes and attachments."); ................................................................................ @ might not work inside a chroot() jail. @ (Property: "max-loadavg")</p> @ <hr /> onoff_attribute( "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript", "auto-hyperlink", "autohyperlink", 1, 0); @ <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 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 forge a User-Agent string that makes them seem to be a @ normal browser and they can run javascript just like browsers. But most @ bots do not 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> @ @ <p>Additional parameters that control this behavior:</p> @ <blockquote> onoff_attribute("Enable hyperlinks for humans as deduced from the UserAgent " "string", "auto-hyperlink-ishuman", "ahis", 0, 0); @ <br /> onoff_attribute("Require mouse movement before enabling hyperlinks", "auto-hyperlink-mouseover", "ahmo", 0, 0); @ <br /> entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, "auto-hyperlink-delay", "ah-delay", "10", 0); @ </blockquote> @ <p>Hyperlinks for user "nobody" are normally enabled as soon as the page @ finishes loading. But the first check-box below can be set to require mouse @ movement before enabling the links. One can also set a delay prior to enabling @ links by enter a positive number of milliseconds in the entry box above.</p> @ (Properties: "auto-hyperlink", "auto-hyperlink-ishuman", @ "auto-hyperlink-mouseover", and "auto-hyperlink-delay")</p> @ <hr /> onoff_attribute("Require a CAPTCHA if not logged in", "require-captcha", "reqcapt", 1, 0); @ <p>Require a CAPTCHA for edit operations (appending, creating, or @ editing wiki or tickets or adding attachments to wiki or tickets) ................................................................................ @ </table> @ @ <p><form action="%s(g.zTop)/setup_login_group" method="post"><div> login_insert_csrf_secret(); @ To leave this login group press @ <input type="submit" value="Leave Login Group" name="leave"> @ </form></p> @ <hr /><h2>Implementation Details</h2> @ <p>The following are fields from the CONFIG table related to login-groups, @ provided here for instructional and debugging purposes:</p> @ <table border='1' id='configTab'> @ <thead><tr><th>Config.Name<th>Config.Value<th>Config.mtime</tr></thead><tbody> db_prepare(&q, "SELECT name, value, datetime(mtime,'unixepoch') FROM config" " WHERE name GLOB 'peer-*'" " OR name GLOB 'project-*'" " ORDER BY name"); while( db_step(&q)==SQLITE_ROW ){ @ <tr><td>%h(db_column_text(&q,0))</td> @ <td>%h(db_column_text(&q,1))</td> @ <td>%h(db_column_text(&q,2))</td></tr> } db_finalize(&q); ................................................................................ /* ** WEBPAGE: setup_settings ** ** Change or view miscellaneous settings. Part of the ** Admin pages requiring Admin privileges. */ void setup_settings(void){ Setting const *pSet; login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } ................................................................................ style_header("Settings"); if(!g.repositoryOpen){ /* Provide read-only access to versioned settings, but only if no repo file was explicitly provided. */ db_open_local(0); } db_begin_transaction(); @ <p>This page provides a simple interface to the "fossil setting" command. @ See the "fossil help setting" output below for further information on @ the meaning of each setting.</p><hr /> @ <form action="%s(g.zTop)/setup_settings" method="post"><div> @ <table border="0"><tr><td valign="top"> login_insert_csrf_secret(); for(pSet=aSetting; pSet->name!=0; pSet++){ if( pSet->width==0 ){ int hasVersionableValue = pSet->versionable && (db_get_versioned(pSet->name, NULL)!=0); onoff_attribute(pSet->name, pSet->name, pSet->var!=0 ? pSet->var : pSet->name, is_truth(pSet->def), hasVersionableValue); if( pSet->versionable ){ @ (v)<br /> } else { @ <br /> } } } @ <br /><input type="submit" name="submit" value="Apply Changes" /> @ </td><td style="width:50px;"></td><td valign="top"> for(pSet=aSetting; pSet->name!=0; pSet++){ if( pSet->width!=0 && !pSet->versionable && !pSet->forceTextArea ){ entry_attribute(pSet->name, /*pSet->width*/ 25, pSet->name, pSet->var!=0 ? pSet->var : pSet->name, (char*)pSet->def, 0); @ <br /> } } for(pSet=aSetting; pSet->name!=0; pSet++){ if( pSet->width!=0 && !pSet->versionable && pSet->forceTextArea ){ @<b>%s(pSet->name)</b><br /> textarea_attribute("", /*rows*/ 3, /*cols*/ 50, pSet->name, pSet->var!=0 ? pSet->var : pSet->name, (char*)pSet->def, 0); @ <br /> } } @ </td><td style="width:50px;"></td><td valign="top"> for(pSet=aSetting; pSet->name!=0; pSet++){ if( pSet->width!=0 && pSet->versionable ){ int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0; @<b>%s(pSet->name)</b> (v)<br /> textarea_attribute("", /*rows*/ 3, /*cols*/ 20, pSet->name, pSet->var!=0 ? pSet->var : pSet->name, (char*)pSet->def, hasVersionableValue); @<br /> } } @ </td></tr></table> @ </div></form> @ <p>Settings marked with (v) are 'versionable' and will be overridden @ by the contents of files named <tt>.fossil-settings/PROPERTY</tt> @ in the check-out root. @ If such a file is present, the corresponding field above is not @ editable.</p><hr /><p> @ These settings work the same as the @ <a href='%R/help?cmd=settings'>fossil set</a> command. db_end_transaction(0); style_footer(); } /* ** WEBPAGE: setup_config ** ................................................................................ @ <hr /> textarea_attribute("Project Description", 3, 80, "project-description", "pd", "", 0); @ <p>Describe your project. This will be used in page headers for search @ engines as well as a short RSS description. @ (Property: "project-description")</p> @ <hr /> entry_attribute("Tarball and ZIP-archive Prefix", 20, "short-project-name", "spn", "", 0); @ <p>This is used as a prefix on the names of generated tarballs and ZIP archive. @ For best results, keep this prefix brief and avoid special characters such @ as "/" and "\". @ If no tarball prefix is specified, then the full Project Name above is used. @ (Property: "short-project-name") @ </p> @ <hr /> onoff_attribute("Enable WYSIWYG Wiki Editing", "wysiwyg-wiki", "wysiwyg-wiki", 0, 0); @ <p>Enable what-you-see-is-what-you-get (WYSIWYG) editing of wiki pages. @ The WYSIWYG editor generates HTML instead of markup, which makes @ subsequent manual editing more difficult. @ (Property: "wysiwyg-wiki")</p> ................................................................................ textarea_attribute("", 6, 80, "adunit-right", "adright", "", 0); @ <br /> onoff_attribute("Omit ads to administrator", "adunit-omit-if-admin", "oia", 0, 0); @ <br /> onoff_attribute("Omit ads to logged-in users", "adunit-omit-if-user", "oiu", 0, 0); @ <br /> @ <input type="submit" name="submit" value="Apply Changes" /> @ <input type="submit" name="clear" value="Delete Ad-Unit" /> @ </div></form> @ <hr /> @ <b>Ad-Unit Notes:</b><ul> @ <li>Leave both Ad-Units blank to disable all advertising. ................................................................................ }else{ @ <pre class="th1error">%h(zR)</pre> } } style_footer(); } static void admin_log_render_limits(){ int const count = db_int(0,"SELECT COUNT(*) FROM admin_log"); int i; int limits[] = { 10, 20, 50, 100, 250, 500, 0 }; for(i = 0; limits[i]; ++i ){ cgi_printf("%s<a href='?n=%d'>%d</a>", i ? " " : "", limits[i], limits[i]); if(limits[i]>count) break; } } /* ** WEBPAGE: admin_log ** ** Shows the contents of the admin_log table, which is only created if ** the admin-log setting is enabled. Requires Admin or Setup ('a' or ** 's') permissions. */ void page_admin_log(){ Stmt stLog = empty_Stmt; Blob qLog = empty_blob; int limit; int fLogEnabled; int counter = 0; login_check_credentials(); if( !g.perm.Setup && !g.perm.Admin ){ login_needed(0); return; } style_header("Admin Log"); create_admin_log_table(); limit = atoi(PD("n","20")); fLogEnabled = db_get_boolean("admin-log", 0); @ <div>Admin logging is %s(fLogEnabled?"on":"off"). @ (Change this on the <a href="setup_settings">settings</a> page.)</div> @ <div>Limit results to: <span> admin_log_render_limits(); @ </span></div> blob_append_sql(&qLog, "SELECT datetime(time,'unixepoch'), who, page, what " "FROM admin_log " "ORDER BY time DESC "); if(limit>0){ @ %d(limit) Most recent entries: blob_append_sql(&qLog, "LIMIT %d", limit); } db_prepare(&stLog, "%s", blob_sql_text(&qLog)); blob_reset(&qLog); @ <table id="adminLogTable" class="adminLogTable" width="100%%"> @ <thead> @ <th>Time</th> @ <th>User</th> @ <th>Page</th> @ <th width="60%%">Message</th> @ </thead><tbody> while( SQLITE_ROW == db_step(&stLog) ){ const char *zTime = db_column_text(&stLog, 0); const char *zUser = db_column_text(&stLog, 1); const char *zPage = db_column_text(&stLog, 2); const char *zMessage = db_column_text(&stLog, 3); @ <tr class="row%d(counter++%2)"> @ <td class="adminTime">%s(zTime)</td> @ <td>%s(zUser)</td> @ <td>%s(zPage)</td> @ <td>%h(zMessage)</td> @ </tr> } @ </tbody></table> if(limit>0 && counter<limit){ @ <div>%d(counter) entries shown.</div> } style_footer(); } /* ** WEBPAGE: srchsetup ** ** Configure the search engine. Requires Admin privilege. ................................................................................ @ <hr /> onoff_attribute("Search Check-in Comments", "search-ci", "sc", 0, 0); @ <br /> onoff_attribute("Search Documents", "search-doc", "sd", 0, 0); @ <br /> onoff_attribute("Search Tickets", "search-tkt", "st", 0, 0); @ <br /> onoff_attribute("Search Wiki","search-wiki", "sw", 0, 0); @ <hr /> @ <p><input type="submit" name="submit" value="Apply Changes" /></p> @ <hr /> if( P("fts0") ){ search_drop_index(); }else if( P("fts1") ){ search_drop_index(); ................................................................................ @ larger repositories.</p> onoff_attribute("Use Porter Stemmer","search-stemmer","ss",0,0); @ <p><input type="submit" name="fts1" value="Create A Full-Text Index"> } @ </div></form> style_footer(); } |
> > | | > > | | < < | | > > | < < < | | | < < | > > > > | > > > > > | | | > > > | | > | | | | | | | | | | | | | < < | | > > | > > > | < < < < < < < | > > > > > > > > > > > > > < < < < < < < < < < < < < < | | | | > < > | | | | | | | | < < < | < < > > > | | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 .... 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 .... 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 .... 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 .... 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 .... 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 .... 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 .... 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 .... 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 .... 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 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 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 |
setup_menu_entry("Login-Group", "setup_login_group", "Manage single sign-on between this repository and others" " on the same server"); setup_menu_entry("Tickets", "tktsetup", "Configure the trouble-ticketing system for this repository"); setup_menu_entry("Search","srchsetup", "Configure the built-in search engine"); setup_menu_entry("URL Aliases", "waliassetup", "Configure URL aliases"); setup_menu_entry("Transfers", "xfersetup", "Configure the transfer system for this repository"); setup_menu_entry("Skins", "setup_skin", "Select and/or modify the web interface \"skins\""); setup_menu_entry("Moderation", "setup_modreq", "Enable/Disable requiring moderator approval of Wiki and/or Ticket" " changes and attachments."); ................................................................................ @ might not work inside a chroot() jail. @ (Property: "max-loadavg")</p> @ <hr /> onoff_attribute( "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript", "auto-hyperlink", "autohyperlink", 1, 0); @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, @ including user "nobody", as long as @ <ol><li>the User-Agent string in the @ HTTP header indicates that the request is coming from an actual human @ being, and @ <li>the user agent is able to @ run Javascript in order to set the href= attribute of hyperlinks, and @ <li>mouse movement is detected (optional - see the checkbox below), and @ <li>a number of milliseconds have passed since the page loaded.</ol> @ @ <p>This setting is designed to give easy access to humans while @ keeping out robots and spiders. @ You do not normally want a robot 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> @ @ <p>Additional parameters that control this behavior:</p> @ <blockquote> onoff_attribute("Require mouse movement before enabling hyperlinks", "auto-hyperlink-mouseover", "ahmo", 0, 0); @ <br /> entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, "auto-hyperlink-delay", "ah-delay", "50", 0); @ </blockquote> @ <p>For maximum robot defense, the "require mouse movement" should @ be turned on and the "Delay" should be at least 50 milliseconds.</p> @ (Properties: "auto-hyperlink", @ "auto-hyperlink-mouseover", and "auto-hyperlink-delay")</p> @ <hr /> onoff_attribute("Require a CAPTCHA if not logged in", "require-captcha", "reqcapt", 1, 0); @ <p>Require a CAPTCHA for edit operations (appending, creating, or @ editing wiki or tickets or adding attachments to wiki or tickets) ................................................................................ @ </table> @ @ <p><form action="%s(g.zTop)/setup_login_group" method="post"><div> login_insert_csrf_secret(); @ To leave this login group press @ <input type="submit" value="Leave Login Group" name="leave"> @ </form></p> @ <br />For best results, use the same number of <a href="setup_access#ipt"> @ IP octets</a> in the login cookie across all repositories in the @ same Login Group. @ <hr /><h2>Implementation Details</h2> @ <p>The following are fields from the CONFIG table related to login-groups, @ provided here for instructional and debugging purposes:</p> @ <table border='1' id='configTab'> @ <thead><tr> @ <th>Config.Name<th>Config.Value<th>Config.mtime</tr> @ </thead><tbody> db_prepare(&q, "SELECT name, value, datetime(mtime,'unixepoch') FROM config" " WHERE name GLOB 'peer-*'" " OR name GLOB 'project-*'" " OR name GLOB 'login-group-*'" " ORDER BY name"); while( db_step(&q)==SQLITE_ROW ){ @ <tr><td>%h(db_column_text(&q,0))</td> @ <td>%h(db_column_text(&q,1))</td> @ <td>%h(db_column_text(&q,2))</td></tr> } db_finalize(&q); ................................................................................ /* ** WEBPAGE: setup_settings ** ** Change or view miscellaneous settings. Part of the ** Admin pages requiring Admin privileges. */ void setup_settings(void){ int nSetting; int i; Setting const *pSet; const Setting *aSetting = setting_info(&nSetting); login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } ................................................................................ style_header("Settings"); if(!g.repositoryOpen){ /* Provide read-only access to versioned settings, but only if no repo file was explicitly provided. */ db_open_local(0); } db_begin_transaction(); @ <p>Settings marked with (v) are "versionable" and will be overridden @ by the contents of managed files named @ "<tt>.fossil-settings/</tt><i>SETTING-NAME</i>". @ If the file for a versionable setting exists, the value cannot be @ changed on this screen.</p><hr /><p> @ @ <form action="%s(g.zTop)/setup_settings" method="post"><div> @ <table border="0"><tr><td valign="top"> login_insert_csrf_secret(); for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){ if( pSet->width==0 ){ int hasVersionableValue = pSet->versionable && (db_get_versioned(pSet->name, NULL)!=0); onoff_attribute("", pSet->name, pSet->var!=0 ? pSet->var : pSet->name, is_truth(pSet->def), hasVersionableValue); @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a> if( pSet->versionable ){ @ (v)<br /> } else { @ <br /> } } } @ <br /><input type="submit" name="submit" value="Apply Changes" /> @ </td><td style="width:50px;"></td><td valign="top"> for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){ if( pSet->width!=0 && !pSet->forceTextArea ){ int hasVersionableValue = pSet->versionable && (db_get_versioned(pSet->name, NULL)!=0); entry_attribute("", /*pSet->width*/ 25, pSet->name, pSet->var!=0 ? pSet->var : pSet->name, (char*)pSet->def, hasVersionableValue); @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a> if( pSet->versionable ){ @ (v)<br /> } else { @ <br /> } } } @ </td><td style="width:50px;"></td><td valign="top"> for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){ if( pSet->width!=0 && pSet->forceTextArea ){ int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0; @ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a> if( pSet->versionable ){ @ (v)<br /> } else { @ <br /> } textarea_attribute("", /*rows*/ 2, /*cols*/ 35, pSet->name, pSet->var!=0 ? pSet->var : pSet->name, (char*)pSet->def, hasVersionableValue); @<br /> } } @ </td></tr></table> @ </div></form> db_end_transaction(0); style_footer(); } /* ** WEBPAGE: setup_config ** ................................................................................ @ <hr /> textarea_attribute("Project Description", 3, 80, "project-description", "pd", "", 0); @ <p>Describe your project. This will be used in page headers for search @ engines as well as a short RSS description. @ (Property: "project-description")</p> @ <hr /> entry_attribute("Tarball and ZIP-archive Prefix", 20, "short-project-name", "spn", "", 0); @ <p>This is used as a prefix on the names of generated tarballs and ZIP archive. @ For best results, keep this prefix brief and avoid special characters such @ as "/" and "\". @ If no tarball prefix is specified, then the full Project Name above is used. @ (Property: "short-project-name") @ </p> @ <hr /> entry_attribute("Download Tag", 20, "download-tag", "dlt", "trunk", 0); @ <p>The <a href='%R/download'>/download</a> page is designed to provide @ a convenient place for newbies @ to download a ZIP archive or a tarball of the project. By default, the latest @ trunk check-in is downloaded. Change this tag to something else (ex: release) @ to alter the behavior of the /download page. @ (Property: "download-tag") @ </p> @ <hr /> onoff_attribute("Enable WYSIWYG Wiki Editing", "wysiwyg-wiki", "wysiwyg-wiki", 0, 0); @ <p>Enable what-you-see-is-what-you-get (WYSIWYG) editing of wiki pages. @ The WYSIWYG editor generates HTML instead of markup, which makes @ subsequent manual editing more difficult. @ (Property: "wysiwyg-wiki")</p> ................................................................................ textarea_attribute("", 6, 80, "adunit-right", "adright", "", 0); @ <br /> onoff_attribute("Omit ads to administrator", "adunit-omit-if-admin", "oia", 0, 0); @ <br /> onoff_attribute("Omit ads to logged-in users", "adunit-omit-if-user", "oiu", 0, 0); @ <br /> onoff_attribute("Temporarily disable all ads", "adunit-disable", "oall", 0, 0); @ <br /> @ <input type="submit" name="submit" value="Apply Changes" /> @ <input type="submit" name="clear" value="Delete Ad-Unit" /> @ </div></form> @ <hr /> @ <b>Ad-Unit Notes:</b><ul> @ <li>Leave both Ad-Units blank to disable all advertising. ................................................................................ }else{ @ <pre class="th1error">%h(zR)</pre> } } style_footer(); } /* ** WEBPAGE: admin_log ** ** Shows the contents of the admin_log table, which is only created if ** the admin-log setting is enabled. Requires Admin or Setup ('a' or ** 's') permissions. */ void page_admin_log(){ Stmt stLog; int limit; /* How many entries to show */ int ofst; /* Offset to the first entry */ int fLogEnabled; int counter = 0; login_check_credentials(); if( !g.perm.Setup && !g.perm.Admin ){ login_needed(0); return; } style_header("Admin Log"); create_admin_log_table(); limit = atoi(PD("n","200")); ofst = atoi(PD("x","0")); fLogEnabled = db_get_boolean("admin-log", 0); @ <div>Admin logging is %s(fLogEnabled?"on":"off"). @ (Change this on the <a href="setup_settings">settings</a> page.)</div> if( ofst>0 ){ int prevx = ofst - limit; if( prevx<0 ) prevx = 0; @ <p><a href="admin_log?n=%d(limit)&x=%d(prevx)">[Newer]</a></p> } db_prepare(&stLog, "SELECT datetime(time,'unixepoch'), who, page, what " "FROM admin_log " "ORDER BY time DESC"); @ <table id="adminLogTable" class="adminLogTable" width="100%%"> @ <thead> @ <th>Time</th> @ <th>User</th> @ <th>Page</th> @ <th width="60%%">Message</th> @ </thead><tbody> while( SQLITE_ROW == db_step(&stLog) ){ const char *zTime = db_column_text(&stLog, 0); const char *zUser = db_column_text(&stLog, 1); const char *zPage = db_column_text(&stLog, 2); const char *zMessage = db_column_text(&stLog, 3); counter++; if( counter<ofst ) continue; if( counter>ofst+limit ) break; @ <tr class="row%d(counter%2)"> @ <td class="adminTime">%s(zTime)</td> @ <td>%s(zUser)</td> @ <td>%s(zPage)</td> @ <td>%h(zMessage)</td> @ </tr> } @ </tbody></table> if( counter>ofst+limit ){ @ <p><a href="admin_log?n=%d(limit)&x=%d(limit+ofst)">[Older]</a></p> } output_table_sorting_javascript("adminLogTable", "Tttx", 1); style_footer(); } /* ** WEBPAGE: srchsetup ** ** Configure the search engine. Requires Admin privilege. ................................................................................ @ <hr /> onoff_attribute("Search Check-in Comments", "search-ci", "sc", 0, 0); @ <br /> onoff_attribute("Search Documents", "search-doc", "sd", 0, 0); @ <br /> onoff_attribute("Search Tickets", "search-tkt", "st", 0, 0); @ <br /> onoff_attribute("Search Wiki", "search-wiki", "sw", 0, 0); @ <br /> onoff_attribute("Search Tech Notes", "search-technote", "se", 0, 0); @ <hr /> @ <p><input type="submit" name="submit" value="Apply Changes" /></p> @ <hr /> if( P("fts0") ){ search_drop_index(); }else if( P("fts1") ){ search_drop_index(); ................................................................................ @ larger repositories.</p> onoff_attribute("Use Porter Stemmer","search-stemmer","ss",0,0); @ <p><input type="submit" name="fts1" value="Create A Full-Text Index"> } @ </div></form> style_footer(); } /* ** A URL Alias originally called zOldName is now zNewName/zValue. ** Write SQL to make this change into pSql. ** ** If zNewName or zValue is an empty string, then delete the entry. ** ** If zOldName is an empty string, create a new entry. */ static void setup_update_url_alias( Blob *pSql, const char *zOldName, const char *zNewName, const char *zValue ){ if( zNewName[0]==0 || zValue[0]==0 ){ if( zOldName[0] ){ blob_append_sql(pSql, "DELETE FROM config WHERE name='walias:%q';\n", zOldName); } return; } if( zOldName[0]==0 ){ blob_append_sql(pSql, "INSERT INTO config(name,value,mtime) VALUES('walias:%q',%Q,now());\n", zNewName, zValue); return; } if( strcmp(zOldName, zNewName)!=0 ){ blob_append_sql(pSql, "UPDATE config SET name='walias:%q', value=%Q, mtime=now()" " WHERE name='walias:%q';\n", zNewName, zValue, zOldName); }else{ blob_append_sql(pSql, "UPDATE config SET value=%Q, mtime=now()" " WHERE name='walias:%q' AND value<>%Q;\n", zValue, zOldName, zValue); } } /* ** WEBPAGE: waliassetup ** ** Configure the URL aliases */ void page_waliassetup(){ Stmt q; int cnt = 0; Blob namelist; login_check_credentials(); if( !g.perm.Setup && !g.perm.Admin ){ login_needed(0); return; } style_header("URL Alias Configuration"); if( P("submit")!=0 ){ Blob token; Blob sql; const char *zNewName; const char *zValue; char zCnt[10]; login_verify_csrf_secret(); blob_init(&namelist, PD("namelist",""), -1); blob_init(&sql, 0, 0); while( blob_token(&namelist, &token) ){ const char *zOldName = blob_str(&token); sqlite3_snprintf(sizeof(zCnt), zCnt, "n%d", cnt); zNewName = PD(zCnt, ""); sqlite3_snprintf(sizeof(zCnt), zCnt, "v%d", cnt); zValue = PD(zCnt, ""); setup_update_url_alias(&sql, zOldName, zNewName, zValue); cnt++; blob_reset(&token); } sqlite3_snprintf(sizeof(zCnt), zCnt, "n%d", cnt); zNewName = PD(zCnt,""); sqlite3_snprintf(sizeof(zCnt), zCnt, "v%d", cnt); zValue = PD(zCnt,""); setup_update_url_alias(&sql, "", zNewName, zValue); db_multi_exec("%s", blob_sql_text(&sql)); blob_reset(&sql); blob_reset(&namelist); cnt = 0; } db_prepare(&q, "SELECT substr(name,8), value FROM config WHERE name GLOB 'walias:/*'" " UNION ALL SELECT '', ''" ); @ <form action="%s(g.zTop)/waliassetup" method="post"><div> login_insert_csrf_secret(); @ <table border=0 cellpadding=5> @ <tr><th>Alias<th>URI That The Alias Maps Into blob_init(&namelist, 0, 0); while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q, 0); const char *zValue = db_column_text(&q, 1); @ <tr><td> @ <input type='text' size='20' value='%h(zName)' name='n%d(cnt)'> @ </td><td> @ <input type='text' size='80' value='%h(zValue)' name='v%d(cnt)'> @ </td></tr> cnt++; if( blob_size(&namelist)>0 ) blob_append(&namelist, " ", 1); blob_append(&namelist, zName, -1); } db_finalize(&q); @ <tr><td> @ <input type='hidden' name='namelist' value='%h(blob_str(&namelist))'> @ <input type='submit' name='submit' value="Apply Changes"> @ </td><td></td></tr> @ </table></form> @ <hr> @ <p>When the first term of an incoming URL exactly matches one of the "Aliases" on @ the left-hand side (LHS) above, the URL is converted into the corresponding form @ on the right-hand side (RHS). @ <ul> @ <li><p> @ The LHS is compared against only the first term of the incoming URL. @ All LHS entries in the alias table should therefore begin with a @ single "/" followed by a single path element. @ <li><p> @ The RHS entries in the alias table should begin with a single "/" followed by @ a path element, and optionally followed by "?" and a list of query parameters. @ <li><p> @ Query parameters on the RHS are added to the set of query parameters @ in the incoming URL. @ <li><p> @ If the same query parameter appears in both the incoming URL and on the RHS of the @ alias, the RHS query parameter value overwrites the value on the incoming URL. @ <li><p> @ If a query parameter on the RHS of the alias is of the form "X!" (a name followed @ by "!") then the X query parameter is removed from the incoming URL if it exists. @ <li><p> @ Only a single alias operation occurs. It is not possible to nest aliases. @ The RHS entries must be built-in webpage names. @ <li><p> @ The alias table is only checked if no built-in webpage matches the incoming URL. @ Hence, it is not possible to override a built-in webpage using aliases. This is @ by design. @ </ul> @ @ <p>To delete an entry from the alias table, change its name or value to an @ empty string and press "Apply Changes". @ @ <p>To add a new alias, fill in the name and value in the bottom row of the table @ above and press "Apply Changes". style_footer(); } |
Changes to src/shell.c.
1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 .... 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 .... 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 .... 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 .... 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 .... 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 .... 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 .... 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 .... 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 .... 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 .... 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 .... 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 .... 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 .... 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 .... 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 .... 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 .... 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 .... 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 .... 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 .... 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 .... 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 .... 8393 8394 8395 8396 8397 8398 8399 8400 |
sqlite3_finalize(pStmt); } sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); } #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_shathree_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; ................................................................................ } fclose(out); sqlite3_result_int64(context, rc); } #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_fileio_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; ................................................................................ #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "completion", &completionModule, 0); #endif return rc; } #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_completion_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; ................................................................................ OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ #endif }; /* ** These are the allowed shellFlgs values */ #define SHFLG_Scratch 0x00000001 /* The --scratch option is used */ #define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */ #define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ #define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ #define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ #define SHFLG_Newlines 0x00000020 /* .dump --newline flag */ #define SHFLG_CountChanges 0x00000040 /* .changes setting */ #define SHFLG_Echo 0x00000080 /* .echo or --echo setting */ /* ** Macros for testing and setting shellFlgs */ #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0) #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) ................................................................................ char **azArg, /* Text of each result column */ char **azCol, /* Column names */ int *aiType /* Column types */ ){ int i; ShellState *p = (ShellState*)pArg; switch( p->cMode ){ case MODE_Line: { int w = 5; if( azArg==0 ) break; for(i=0; i<nArg; i++){ int len = strlen30(azCol[i] ? azCol[i] : ""); if( len>w ) w = len; ................................................................................ break; } z = sqlite3_mprintf("%s", azArg[0]); j = 0; for(i=0; IsSpace(z[i]); i++){} for(; (c = z[i])!=0; i++){ if( IsSpace(c) ){ if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ j--; } z[j++] = c; } while( j>0 && IsSpace(z[j-1]) ){ j--; } ................................................................................ ** This is the callback routine from sqlite3_exec() that appends all ** output onto the end of a ShellText object. */ static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ ShellText *p = (ShellText*)pArg; int i; UNUSED_PARAMETER(az); if( p->n ) appendText(p, "|", 0); for(i=0; i<nArg; i++){ if( i ) appendText(p, ",", 0); if( azArg[i] ) appendText(p, azArg[i], 0); } return 0; } ................................................................................ /* ** Set the destination table field of the ShellState structure to ** the name of the table given. Escape any quote characters in the ** table name. */ static void set_table_name(ShellState *p, const char *zName){ int i, n; int cQuote; char *z; if( p->zDestTable ){ free(p->zDestTable); p->zDestTable = 0; } if( zName==0 ) return; ................................................................................ "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); if( pArg->shellFlgs & SHFLG_Pagecache ){ displayStatLine(pArg, "Number of Pcache Pages Used:", "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); } displayStatLine(pArg, "Number of Pcache Overflow Bytes:", "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); if( pArg->shellFlgs & SHFLG_Scratch ){ displayStatLine(pArg, "Number of Scratch Allocations Used:", "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); } displayStatLine(pArg, "Number of Scratch Overflow Bytes:", "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); displayStatLine(pArg, "Largest Allocation:", "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); displayStatLine(pArg, "Largest Pcache Allocation:", "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); displayStatLine(pArg, "Largest Scratch Allocation:", "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); #ifdef YYTRACKMAXSTACKDEPTH displayStatLine(pArg, "Deepest Parser Stack:", "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); #endif } if( pArg && pArg->out && db ){ ................................................................................ isIPK = 1; }else{ isIPK = 0; } } } sqlite3_finalize(pStmt); azCol[0] = 0; azCol[nCol+1] = 0; /* The decision of whether or not a rowid really needs to be preserved ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve ** rowids on tables where the rowid is inaccessible because there are other ................................................................................ int rc; const char *zTable; const char *zType; const char *zSql; ShellState *p = (ShellState *)pArg; UNUSED_PARAMETER(azNotUsed); if( nArg!=3 ) return 1; zTable = azArg[0]; zType = azArg[1]; zSql = azArg[2]; if( strcmp(zTable, "sqlite_sequence")==0 ){ raw_printf(p->out, "DELETE FROM sqlite_sequence;\n"); }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ ................................................................................ ** Readline completion callbacks */ static char *readline_completion_generator(const char *text, int state){ static sqlite3_stmt *pStmt = 0; char *zRet; if( state==0 ){ char *zSql; int rc; sqlite3_finalize(pStmt); zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" " FROM completion(%Q) ORDER BY 1", text); sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); sqlite3_free(zSql); } if( sqlite3_step(pStmt)==SQLITE_ROW ){ zRet = strdup(sqlite3_column_text(pStmt, 0)); }else{ sqlite3_finalize(pStmt); pStmt = 0; zRet = 0; } return zRet; } ................................................................................ { "number of triggers:", "SELECT count(*) FROM %s WHERE type='trigger'" }, { "number of views:", "SELECT count(*) FROM %s WHERE type='view'" }, { "schema size:", "SELECT total(length(sql)) FROM %s" }, }; sqlite3_file *pFile = 0; int i; char *zSchemaTab; char *zDb = nArg>=2 ? azArg[1] : "main"; unsigned char aHdr[100]; open_db(p, 0); if( p->db==0 ) return 1; sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ return 1; } i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); if( i!=SQLITE_OK ){ raw_printf(stderr, "unable to read database header\n"); return 1; } i = get2byteInt(aHdr+16); if( i==1 ) i = 65536; utf8_printf(p->out, "%-20s %d\n", "database page size:", i); utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]); utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]); ................................................................................ }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); rc = 2; }else if( testcase_glob(azArg[1],zRes)==0 ){ utf8_printf(stderr, "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", p->zTestcase, azArg[1], zRes); rc = 2; }else{ utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); p->nCheck++; } sqlite3_free(zRes); }else ................................................................................ { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, { "assert", SQLITE_TESTCTRL_ASSERT }, { "always", SQLITE_TESTCTRL_ALWAYS }, { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, { "imposter", SQLITE_TESTCTRL_IMPOSTER }, }; int testctrl = -1; int rc2 = 0; int i, n2; ................................................................................ raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); } break; case SQLITE_TESTCTRL_BITVEC_TEST: case SQLITE_TESTCTRL_FAULT_INSTALL: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: case SQLITE_TESTCTRL_SCRATCHMALLOC: default: utf8_printf(stderr, "Error: CLI support for testctrl %s not implemented\n", azArg[1]); break; } } ................................................................................ #ifdef SQLITE_ENABLE_MULTIPLEX " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -quote set output mode to 'quote'\n" " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" " -separator SEP set output column separator. Default: '|'\n" " -stats print memory stats before each finalize\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" #ifdef SQLITE_ENABLE_VFSTRACE " -vfstrace enable tracing of all VFS calls\n" #endif ................................................................................ setBinaryMode(stdin, 0); setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); #if USE_SYSTEM_SQLITE+0!=1 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); } #endif main_init(&data); #if !SQLITE_SHELL_IS_UTF8 ................................................................................ zSize = cmdline_option_value(argc, argv, ++i); szHeap = integerValue(zSize); if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); #else (void)cmdline_option_value(argc, argv, ++i); #endif }else if( strcmp(z,"-scratch")==0 ){ int n, sz; sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); if( sz>400000 ) sz = 400000; if( sz<2500 ) sz = 2500; n = (int)integerValue(cmdline_option_value(argc,argv,++i)); if( n>10 ) n = 10; if( n<1 ) n = 1; sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); data.shellFlgs |= SHFLG_Scratch; }else if( strcmp(z,"-pagecache")==0 ){ int n, sz; sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); if( sz>70000 ) sz = 70000; if( sz<0 ) sz = 0; n = (int)integerValue(cmdline_option_value(argc,argv,++i)); sqlite3_config(SQLITE_CONFIG_PAGECACHE, ................................................................................ return 0; }else if( strcmp(z,"-interactive")==0 ){ stdin_is_interactive = 1; }else if( strcmp(z,"-batch")==0 ){ stdin_is_interactive = 0; }else if( strcmp(z,"-heap")==0 ){ i++; }else if( strcmp(z,"-scratch")==0 ){ i+=2; }else if( strcmp(z,"-pagecache")==0 ){ i+=2; }else if( strcmp(z,"-lookaside")==0 ){ i+=2; }else if( strcmp(z,"-mmap")==0 ){ i++; }else if( strcmp(z,"-vfs")==0 ){ ................................................................................ #if HAVE_READLINE || HAVE_EDITLINE rl_attempted_completion_function = readline_completion; #elif HAVE_LINENOISE linenoiseSetCompletionCallback(linenoise_completion); #endif rc = process_input(&data, 0); if( zHistory ){ shell_stifle_history(100); shell_write_history(zHistory); free(zHistory); } }else{ rc = process_input(&data, stdin); } } ................................................................................ find_home_dir(1); #if !SQLITE_SHELL_IS_UTF8 for(i=0; i<argc; i++) sqlite3_free(argv[i]); sqlite3_free(argv); #endif return rc; } |
| | | < | | | | | | | > > > | < < < < < < < < > | < | < > | | | < > | | > > > > | < < < | < < < < < < < < < < < < | < |
1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 .... 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 .... 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 .... 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 .... 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 .... 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 .... 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 .... 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 .... 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 .... 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 .... 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 .... 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 .... 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 .... 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 .... 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 .... 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 .... 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 .... 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 .... 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 .... 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 .... 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 .... 8376 8377 8378 8379 8380 8381 8382 |
sqlite3_finalize(pStmt); } sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); } #ifdef _WIN32 #endif int sqlite3_shathree_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; ................................................................................ } fclose(out); sqlite3_result_int64(context, rc); } #ifdef _WIN32 #endif int sqlite3_fileio_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; ................................................................................ #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "completion", &completionModule, 0); #endif return rc; } #ifdef _WIN32 #endif int sqlite3_completion_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; ................................................................................ OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ #endif }; /* ** These are the allowed shellFlgs values */ #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */ #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */ #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */ #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */ #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ #define SHFLG_CountChanges 0x00000020 /* .changes setting */ #define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ /* ** Macros for testing and setting shellFlgs */ #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0) #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) ................................................................................ char **azArg, /* Text of each result column */ char **azCol, /* Column names */ int *aiType /* Column types */ ){ int i; ShellState *p = (ShellState*)pArg; if( azArg==0 ) return 0; switch( p->cMode ){ case MODE_Line: { int w = 5; if( azArg==0 ) break; for(i=0; i<nArg; i++){ int len = strlen30(azCol[i] ? azCol[i] : ""); if( len>w ) w = len; ................................................................................ break; } z = sqlite3_mprintf("%s", azArg[0]); j = 0; for(i=0; IsSpace(z[i]); i++){} for(; (c = z[i])!=0; i++){ if( IsSpace(c) ){ if( z[j-1]=='\r' ) z[j-1] = '\n'; if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ j--; } z[j++] = c; } while( j>0 && IsSpace(z[j-1]) ){ j--; } ................................................................................ ** This is the callback routine from sqlite3_exec() that appends all ** output onto the end of a ShellText object. */ static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ ShellText *p = (ShellText*)pArg; int i; UNUSED_PARAMETER(az); if( azArg==0 ) return 0; if( p->n ) appendText(p, "|", 0); for(i=0; i<nArg; i++){ if( i ) appendText(p, ",", 0); if( azArg[i] ) appendText(p, azArg[i], 0); } return 0; } ................................................................................ /* ** Set the destination table field of the ShellState structure to ** the name of the table given. Escape any quote characters in the ** table name. */ static void set_table_name(ShellState *p, const char *zName){ int i, n; char cQuote; char *z; if( p->zDestTable ){ free(p->zDestTable); p->zDestTable = 0; } if( zName==0 ) return; ................................................................................ "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); if( pArg->shellFlgs & SHFLG_Pagecache ){ displayStatLine(pArg, "Number of Pcache Pages Used:", "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); } displayStatLine(pArg, "Number of Pcache Overflow Bytes:", "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); displayStatLine(pArg, "Largest Allocation:", "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); displayStatLine(pArg, "Largest Pcache Allocation:", "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); #ifdef YYTRACKMAXSTACKDEPTH displayStatLine(pArg, "Deepest Parser Stack:", "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); #endif } if( pArg && pArg->out && db ){ ................................................................................ isIPK = 1; }else{ isIPK = 0; } } } sqlite3_finalize(pStmt); if( azCol==0 ) return 0; azCol[0] = 0; azCol[nCol+1] = 0; /* The decision of whether or not a rowid really needs to be preserved ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve ** rowids on tables where the rowid is inaccessible because there are other ................................................................................ int rc; const char *zTable; const char *zType; const char *zSql; ShellState *p = (ShellState *)pArg; UNUSED_PARAMETER(azNotUsed); if( nArg!=3 || azArg==0 ) return 0; zTable = azArg[0]; zType = azArg[1]; zSql = azArg[2]; if( strcmp(zTable, "sqlite_sequence")==0 ){ raw_printf(p->out, "DELETE FROM sqlite_sequence;\n"); }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ ................................................................................ ** Readline completion callbacks */ static char *readline_completion_generator(const char *text, int state){ static sqlite3_stmt *pStmt = 0; char *zRet; if( state==0 ){ char *zSql; sqlite3_finalize(pStmt); zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" " FROM completion(%Q) ORDER BY 1", text); sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); sqlite3_free(zSql); } if( sqlite3_step(pStmt)==SQLITE_ROW ){ zRet = strdup((const char*)sqlite3_column_text(pStmt, 0)); }else{ sqlite3_finalize(pStmt); pStmt = 0; zRet = 0; } return zRet; } ................................................................................ { "number of triggers:", "SELECT count(*) FROM %s WHERE type='trigger'" }, { "number of views:", "SELECT count(*) FROM %s WHERE type='view'" }, { "schema size:", "SELECT total(length(sql)) FROM %s" }, }; int i; char *zSchemaTab; char *zDb = nArg>=2 ? azArg[1] : "main"; sqlite3_stmt *pStmt = 0; unsigned char aHdr[100]; open_db(p, 0); if( p->db==0 ) return 1; sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1", -1, &pStmt, 0); sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC); if( sqlite3_step(pStmt)==SQLITE_ROW && sqlite3_column_bytes(pStmt,0)>100 ){ memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100); sqlite3_finalize(pStmt); }else{ raw_printf(stderr, "unable to read database header\n"); sqlite3_finalize(pStmt); return 1; } i = get2byteInt(aHdr+16); if( i==1 ) i = 65536; utf8_printf(p->out, "%-20s %d\n", "database page size:", i); utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]); utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]); ................................................................................ }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); rc = 2; }else if( testcase_glob(azArg[1],zRes)==0 ){ utf8_printf(stderr, "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", p->zTestcase, azArg[1], zRes); rc = 1; }else{ utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); p->nCheck++; } sqlite3_free(zRes); }else ................................................................................ { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, { "assert", SQLITE_TESTCTRL_ASSERT }, { "always", SQLITE_TESTCTRL_ALWAYS }, { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, { "imposter", SQLITE_TESTCTRL_IMPOSTER }, }; int testctrl = -1; int rc2 = 0; int i, n2; ................................................................................ raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); } break; case SQLITE_TESTCTRL_BITVEC_TEST: case SQLITE_TESTCTRL_FAULT_INSTALL: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: default: utf8_printf(stderr, "Error: CLI support for testctrl %s not implemented\n", azArg[1]); break; } } ................................................................................ #ifdef SQLITE_ENABLE_MULTIPLEX " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -quote set output mode to 'quote'\n" " -separator SEP set output column separator. Default: '|'\n" " -stats print memory stats before each finalize\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" #ifdef SQLITE_ENABLE_VFSTRACE " -vfstrace enable tracing of all VFS calls\n" #endif ................................................................................ setBinaryMode(stdin, 0); setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); #if USE_SYSTEM_SQLITE+0!=1 if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); } #endif main_init(&data); #if !SQLITE_SHELL_IS_UTF8 ................................................................................ zSize = cmdline_option_value(argc, argv, ++i); szHeap = integerValue(zSize); if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); #else (void)cmdline_option_value(argc, argv, ++i); #endif }else if( strcmp(z,"-pagecache")==0 ){ int n, sz; sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); if( sz>70000 ) sz = 70000; if( sz<0 ) sz = 0; n = (int)integerValue(cmdline_option_value(argc,argv,++i)); sqlite3_config(SQLITE_CONFIG_PAGECACHE, ................................................................................ return 0; }else if( strcmp(z,"-interactive")==0 ){ stdin_is_interactive = 1; }else if( strcmp(z,"-batch")==0 ){ stdin_is_interactive = 0; }else if( strcmp(z,"-heap")==0 ){ i++; }else if( strcmp(z,"-pagecache")==0 ){ i+=2; }else if( strcmp(z,"-lookaside")==0 ){ i+=2; }else if( strcmp(z,"-mmap")==0 ){ i++; }else if( strcmp(z,"-vfs")==0 ){ ................................................................................ #if HAVE_READLINE || HAVE_EDITLINE rl_attempted_completion_function = readline_completion; #elif HAVE_LINENOISE linenoiseSetCompletionCallback(linenoise_completion); #endif rc = process_input(&data, 0); if( zHistory ){ shell_stifle_history(2000); shell_write_history(zHistory); free(zHistory); } }else{ rc = process_input(&data, stdin); } } ................................................................................ find_home_dir(1); #if !SQLITE_SHELL_IS_UTF8 for(i=0; i<argc; i++) sqlite3_free(argv[i]); sqlite3_free(argv); #endif return rc; } |
Changes to src/shun.c.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
}else{ style_submenu_element("All", "rcvfromlist?all=1"); } if( ofst>0 ){ style_submenu_element("Newer", "rcvfromlist?ofst=%d", ofst>perScreen ? ofst-perScreen : 0); } db_multi_exec( "CREATE TEMP TABLE rcvidUsed(x INTEGER PRIMARY KEY);" "CREATE TEMP TABLE rcvidSha1(x INTEGER PRIMARY KEY);" "CREATE TEMP TABLE rcvidSha3(x INTEGER PRIMARY KEY);" "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM blob;" "INSERT OR IGNORE INTO rcvidSha1(x)" " SELECT rcvid FROM blob WHERE length(uuid)==40;" |
> > |
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
}else{ style_submenu_element("All", "rcvfromlist?all=1"); } if( ofst>0 ){ style_submenu_element("Newer", "rcvfromlist?ofst=%d", ofst>perScreen ? ofst-perScreen : 0); } style_submenu_element("Artifacts", "bloblist"); style_submenu_element("Top-250", "bigbloblist"); db_multi_exec( "CREATE TEMP TABLE rcvidUsed(x INTEGER PRIMARY KEY);" "CREATE TEMP TABLE rcvidSha1(x INTEGER PRIMARY KEY);" "CREATE TEMP TABLE rcvidSha3(x INTEGER PRIMARY KEY);" "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM blob;" "INSERT OR IGNORE INTO rcvidSha1(x)" " SELECT rcvid FROM blob WHERE length(uuid)==40;" |
Changes to src/sqlite3.c.
1 2 3 4 5 6 7 8 9 10 ... 204 205 206 207 208 209 210 211 212 213 214 215 216 217 ... 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 .... 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 .... 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 .... 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 .... 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 .... 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 .... 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 .... 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 .... 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 .... 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 .... 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 .... 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 .... 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 .... 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 .... 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 .... 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 .... 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 .... 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 .... 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 .... 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 .... 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 .... 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 .... 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 .... 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 .... 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 .... 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 .... 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 .... 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 .... 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 .... 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 .... 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 .... 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 .... 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 .... 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 .... 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 .... 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 .... 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 .... 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 .... 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 .... 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 .... 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 .... 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 .... 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 .... 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 .... 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 .... 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 ..... 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 ..... 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 ..... 12187 12188 12189 12190 12191 12192 12193 12194 12195 12196 12197 12198 12199 12200 ..... 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416 12417 12418 12419 12420 12421 12422 12423 12424 12425 12426 12427 12428 12429 12430 12431 12432 12433 12434 12435 12436 12437 12438 12439 12440 12441 12442 12443 12444 12445 12446 12447 12448 12449 12450 12451 ..... 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 12523 12524 12525 12526 12527 12528 12529 12530 12531 12532 ..... 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 ..... 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 ..... 13340 13341 13342 13343 13344 13345 13346 13347 13348 13349 13350 13351 13352 13353 ..... 13593 13594 13595 13596 13597 13598 13599 13600 13601 13602 13603 13604 13605 13606 13607 13608 13609 13610 13611 13612 13613 13614 13615 13616 13617 13618 13619 13620 13621 13622 13623 13624 ..... 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674 13675 13676 13677 13678 13679 13680 13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693 13694 13695 13696 13697 13698 13699 13700 13701 13702 13703 13704 13705 13706 13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 13721 13722 13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 13738 13739 13740 13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 13764 13765 13766 13767 13768 13769 13770 13771 13772 13773 13774 13775 13776 13777 13778 13779 13780 13781 13782 13783 13784 13785 13786 13787 13788 13789 13790 13791 13792 13793 13794 13795 13796 13797 13798 13799 13800 13801 13802 13803 13804 13805 13806 13807 13808 13809 13810 13811 13812 13813 13814 13815 13816 13817 13818 13819 13820 13821 13822 13823 13824 13825 13826 13827 13828 13829 13830 13831 13832 ..... 13836 13837 13838 13839 13840 13841 13842 13843 13844 13845 13846 13847 13848 13849 13850 13851 13852 13853 13854 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 13869 13870 13871 13872 13873 ..... 13949 13950 13951 13952 13953 13954 13955 13956 13957 13958 13959 13960 13961 13962 ..... 14175 14176 14177 14178 14179 14180 14181 14182 14183 14184 14185 14186 14187 14188 ..... 14311 14312 14313 14314 14315 14316 14317 14318 14319 14320 14321 14322 14323 14324 ..... 14692 14693 14694 14695 14696 14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 ..... 14904 14905 14906 14907 14908 14909 14910 14911 14912 14913 14914 14915 14916 14917 ..... 14935 14936 14937 14938 14939 14940 14941 14942 14943 14944 14945 14946 14947 14948 14949 14950 14951 ..... 15016 15017 15018 15019 15020 15021 15022 15023 15024 15025 15026 15027 15028 15029 15030 15031 15032 ..... 15170 15171 15172 15173 15174 15175 15176 15177 15178 15179 15180 15181 15182 15183 15184 15185 15186 15187 15188 15189 15190 15191 15192 15193 15194 15195 15196 15197 15198 15199 15200 15201 15202 15203 15204 15205 15206 15207 15208 15209 15210 15211 15212 15213 15214 15215 15216 15217 15218 15219 15220 15221 15222 15223 15224 ..... 15328 15329 15330 15331 15332 15333 15334 15335 15336 15337 15338 15339 15340 15341 15342 ..... 15351 15352 15353 15354 15355 15356 15357 15358 15359 15360 15361 15362 15363 15364 15365 15366 ..... 15731 15732 15733 15734 15735 15736 15737 15738 15739 15740 15741 15742 15743 15744 15745 15746 ..... 15779 15780 15781 15782 15783 15784 15785 15786 15787 15788 15789 15790 15791 15792 15793 15794 ..... 16064 16065 16066 16067 16068 16069 16070 16071 16072 16073 16074 16075 16076 16077 16078 ..... 16152 16153 16154 16155 16156 16157 16158 16159 16160 16161 16162 16163 16164 16165 16166 ..... 16653 16654 16655 16656 16657 16658 16659 16660 16661 16662 16663 16664 16665 16666 16667 16668 ..... 16677 16678 16679 16680 16681 16682 16683 16684 16685 16686 16687 16688 16689 16690 16691 ..... 16906 16907 16908 16909 16910 16911 16912 16913 16914 16915 16916 16917 16918 16919 16920 16921 16922 16923 16924 ..... 16945 16946 16947 16948 16949 16950 16951 16952 16953 16954 16955 16956 16957 16958 16959 16960 16961 16962 16963 16964 16965 16966 16967 16968 16969 16970 16971 16972 16973 16974 ..... 17047 17048 17049 17050 17051 17052 17053 17054 17055 17056 17057 17058 17059 17060 ..... 17199 17200 17201 17202 17203 17204 17205 17206 17207 17208 17209 17210 17211 17212 17213 17214 ..... 17256 17257 17258 17259 17260 17261 17262 17263 17264 17265 17266 17267 17268 17269 ..... 17692 17693 17694 17695 17696 17697 17698 17699 17700 17701 17702 17703 17704 17705 ..... 17975 17976 17977 17978 17979 17980 17981 17982 17983 17984 17985 17986 17987 17988 17989 ..... 18061 18062 18063 18064 18065 18066 18067 18068 18069 18070 18071 18072 18073 18074 18075 18076 18077 18078 18079 18080 18081 18082 18083 18084 18085 ..... 18291 18292 18293 18294 18295 18296 18297 18298 18299 18300 18301 18302 18303 18304 18305 18306 18307 18308 18309 18310 18311 18312 18313 18314 18315 18316 18317 18318 18319 ..... 18507 18508 18509 18510 18511 18512 18513 18514 18515 18516 18517 18518 18519 18520 18521 18522 18523 18524 18525 18526 18527 18528 18529 18530 18531 18532 ..... 18600 18601 18602 18603 18604 18605 18606 18607 18608 18609 18610 18611 18612 18613 18614 ..... 18632 18633 18634 18635 18636 18637 18638 18639 18640 18641 18642 18643 18644 18645 18646 18647 18648 18649 18650 18651 18652 18653 18654 18655 18656 18657 18658 18659 18660 18661 18662 18663 18664 18665 18666 18667 18668 18669 18670 18671 18672 ..... 18886 18887 18888 18889 18890 18891 18892 18893 18894 18895 18896 18897 18898 18899 ..... 19073 19074 19075 19076 19077 19078 19079 19080 19081 19082 19083 19084 19085 19086 19087 ..... 19121 19122 19123 19124 19125 19126 19127 19128 19129 19130 19131 19132 19133 19134 ..... 19141 19142 19143 19144 19145 19146 19147 19148 19149 19150 19151 19152 19153 19154 19155 19156 19157 19158 ..... 19691 19692 19693 19694 19695 19696 19697 19698 19699 19700 19701 19702 19703 19704 19705 ..... 19974 19975 19976 19977 19978 19979 19980 19981 19982 19983 19984 19985 19986 19987 19988 ..... 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010 20011 20012 20013 20014 ..... 20536 20537 20538 20539 20540 20541 20542 20543 20544 20545 20546 20547 20548 20549 20550 20551 20552 20553 20554 ..... 20655 20656 20657 20658 20659 20660 20661 20662 20663 20664 20665 20666 20667 20668 20669 ..... 20710 20711 20712 20713 20714 20715 20716 20717 20718 20719 20720 20721 20722 20723 ..... 20729 20730 20731 20732 20733 20734 20735 20736 20737 20738 20739 20740 20741 20742 ..... 24725 24726 24727 24728 24729 24730 24731 24732 24733 24734 24735 24736 24737 24738 24739 24740 24741 24742 24743 24744 24745 24746 24747 24748 24749 24750 24751 24752 24753 24754 24755 24756 24757 24758 24759 24760 24761 24762 24763 24764 24765 24766 24767 24768 24769 ..... 24825 24826 24827 24828 24829 24830 24831 24832 24833 24834 24835 24836 24837 24838 24839 24840 24841 24842 24843 24844 24845 24846 24847 24848 24849 24850 24851 24852 24853 24854 24855 24856 24857 24858 24859 24860 ..... 24997 24998 24999 25000 25001 25002 25003 25004 25005 25006 25007 25008 25009 25010 25011 25012 25013 25014 25015 25016 25017 25018 25019 25020 25021 25022 25023 25024 25025 25026 25027 25028 25029 25030 25031 25032 25033 25034 25035 25036 25037 25038 25039 25040 25041 25042 25043 25044 25045 25046 25047 25048 25049 25050 25051 25052 25053 25054 25055 25056 25057 25058 25059 25060 25061 25062 25063 25064 25065 25066 25067 25068 25069 25070 25071 25072 25073 25074 25075 25076 25077 25078 25079 25080 25081 25082 25083 25084 25085 25086 25087 25088 25089 25090 25091 25092 25093 25094 25095 25096 25097 25098 25099 25100 25101 25102 25103 25104 25105 25106 25107 25108 25109 ..... 25186 25187 25188 25189 25190 25191 25192 25193 25194 25195 25196 25197 25198 25199 25200 ..... 25347 25348 25349 25350 25351 25352 25353 25354 25355 25356 25357 25358 25359 25360 25361 25362 25363 25364 25365 25366 25367 25368 25369 25370 ..... 26194 26195 26196 26197 26198 26199 26200 26201 26202 26203 26204 26205 26206 26207 26208 ..... 26320 26321 26322 26323 26324 26325 26326 26327 26328 26329 26330 26331 26332 26333 26334 ..... 26362 26363 26364 26365 26366 26367 26368 26369 26370 26371 26372 26373 26374 26375 26376 ..... 26380 26381 26382 26383 26384 26385 26386 26387 26388 26389 26390 26391 26392 26393 26394 ..... 26415 26416 26417 26418 26419 26420 26421 26422 26423 26424 26425 26426 26427 26428 26429 26430 26431 26432 26433 26434 26435 26436 26437 26438 26439 26440 26441 26442 26443 26444 26445 26446 26447 26448 26449 26450 26451 26452 26453 26454 ..... 26463 26464 26465 26466 26467 26468 26469 26470 26471 26472 26473 26474 26475 26476 26477 26478 26479 26480 26481 ..... 28628 28629 28630 28631 28632 28633 28634 28635 28636 28637 28638 28639 28640 28641 28642 ..... 28690 28691 28692 28693 28694 28695 28696 28697 28698 28699 28700 28701 28702 28703 28704 28705 28706 28707 28708 28709 28710 28711 28712 28713 28714 28715 28716 28717 28718 28719 28720 28721 28722 28723 28724 28725 ..... 28751 28752 28753 28754 28755 28756 28757 28758 28759 28760 28761 28762 28763 28764 28765 28766 28767 28768 28769 28770 28771 28772 28773 28774 28775 28776 28777 28778 28779 28780 28781 28782 28783 28784 28785 28786 28787 28788 28789 28790 28791 28792 28793 28794 28795 28796 28797 28798 28799 28800 28801 28802 28803 28804 28805 28806 28807 28808 28809 28810 28811 28812 28813 28814 28815 28816 28817 ..... 29413 29414 29415 29416 29417 29418 29419 29420 29421 29422 29423 29424 29425 29426 29427 ..... 29433 29434 29435 29436 29437 29438 29439 29440 29441 29442 29443 29444 29445 29446 29447 ..... 29448 29449 29450 29451 29452 29453 29454 29455 29456 29457 29458 29459 29460 29461 29462 ..... 29550 29551 29552 29553 29554 29555 29556 29557 29558 29559 29560 29561 29562 29563 29564 29565 ..... 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 30082 30083 30084 30085 30086 30087 30088 30089 30090 30091 30092 30093 30094 30095 30096 30097 30098 30099 30100 30101 30102 30103 30104 30105 30106 30107 30108 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 ..... 30254 30255 30256 30257 30258 30259 30260 30261 30262 30263 30264 30265 30266 30267 30268 30269 30270 30271 30272 30273 30274 30275 30276 30277 ..... 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 ..... 30689 30690 30691 30692 30693 30694 30695 30696 30697 30698 30699 30700 30701 30702 ..... 30861 30862 30863 30864 30865 30866 30867 30868 30869 30870 30871 30872 30873 30874 ..... 31466 31467 31468 31469 31470 31471 31472 31473 31474 31475 31476 31477 31478 31479 31480 ..... 31576 31577 31578 31579 31580 31581 31582 31583 31584 31585 31586 31587 31588 31589 ..... 31608 31609 31610 31611 31612 31613 31614 31615 31616 31617 31618 31619 31620 31621 ..... 31677 31678 31679 31680 31681 31682 31683 31684 31685 31686 31687 31688 31689 31690 ..... 32096 32097 32098 32099 32100 32101 32102 32103 32104 32105 32106 32107 32108 32109 32110 32111 32112 32113 32114 ..... 32325 32326 32327 32328 32329 32330 32331 32332 32333 32334 32335 32336 32337 32338 32339 ..... 32662 32663 32664 32665 32666 32667 32668 32669 32670 32671 32672 32673 32674 32675 32676 ..... 32729 32730 32731 32732 32733 32734 32735 32736 32737 32738 32739 32740 32741 32742 32743 ..... 33266 33267 33268 33269 33270 33271 33272 33273 33274 33275 33276 33277 33278 33279 33280 ..... 33546 33547 33548 33549 33550 33551 33552 33553 33554 33555 33556 33557 33558 33559 33560 ..... 33659 33660 33661 33662 33663 33664 33665 33666 33667 33668 33669 33670 33671 33672 33673 ..... 34139 34140 34141 34142 34143 34144 34145 34146 34147 34148 34149 34150 34151 34152 ..... 34189 34190 34191 34192 34193 34194 34195 34196 34197 34198 34199 34200 34201 34202 ..... 34222 34223 34224 34225 34226 34227 34228 34229 34230 34231 34232 34233 34234 34235 34236 34237 34238 34239 34240 34241 34242 34243 34244 34245 34246 34247 34248 34249 34250 34251 34252 34253 34254 34255 34256 34257 34258 34259 ..... 34314 34315 34316 34317 34318 34319 34320 34321 34322 34323 34324 34325 34326 34327 34328 34329 34330 ..... 34332 34333 34334 34335 34336 34337 34338 34339 34340 34341 34342 34343 34344 34345 34346 34347 34348 34349 34350 34351 34352 34353 34354 34355 ..... 35599 35600 35601 35602 35603 35604 35605 35606 35607 35608 35609 35610 35611 35612 35613 35614 35615 35616 35617 35618 35619 35620 35621 35622 35623 ..... 35867 35868 35869 35870 35871 35872 35873 35874 35875 35876 35877 35878 35879 35880 35881 35882 35883 35884 35885 35886 35887 35888 35889 35890 35891 35892 35893 35894 35895 35896 35897 35898 35899 35900 35901 35902 35903 35904 35905 35906 35907 35908 ..... 35970 35971 35972 35973 35974 35975 35976 35977 35978 35979 35980 35981 35982 35983 35984 35985 35986 35987 35988 35989 35990 35991 35992 35993 ..... 36115 36116 36117 36118 36119 36120 36121 36122 36123 36124 36125 36126 36127 36128 36129 ..... 36152 36153 36154 36155 36156 36157 36158 36159 36160 36161 36162 36163 36164 36165 36166 ..... 36186 36187 36188 36189 36190 36191 36192 36193 36194 36195 36196 36197 36198 36199 36200 36201 36202 ..... 36265 36266 36267 36268 36269 36270 36271 36272 36273 36274 36275 36276 36277 36278 36279 36280 36281 36282 36283 ..... 37010 37011 37012 37013 37014 37015 37016 37017 37018 37019 37020 37021 37022 37023 37024 ..... 37960 37961 37962 37963 37964 37965 37966 37967 37968 37969 37970 37971 37972 37973 37974 ..... 41743 41744 41745 41746 41747 41748 41749 41750 41751 41752 41753 41754 41755 41756 ..... 43055 43056 43057 43058 43059 43060 43061 43062 43063 43064 43065 43066 43067 43068 ..... 43231 43232 43233 43234 43235 43236 43237 43238 43239 43240 43241 43242 43243 43244 43245 43246 43247 43248 43249 43250 43251 43252 43253 43254 43255 43256 43257 43258 43259 43260 43261 43262 43263 43264 43265 43266 43267 43268 43269 43270 43271 43272 43273 43274 43275 43276 43277 43278 43279 43280 43281 43282 43283 43284 43285 43286 43287 43288 43289 43290 43291 43292 43293 ..... 43872 43873 43874 43875 43876 43877 43878 43879 43880 43881 43882 43883 43884 43885 43886 43887 43888 ..... 44793 44794 44795 44796 44797 44798 44799 44800 44801 44802 44803 44804 44805 44806 44807 44808 44809 44810 44811 44812 ..... 45115 45116 45117 45118 45119 45120 45121 45122 45123 45124 45125 45126 45127 45128 45129 45130 45131 45132 45133 ..... 45580 45581 45582 45583 45584 45585 45586 45587 45588 45589 45590 45591 45592 45593 45594 45595 45596 45597 45598 45599 45600 45601 45602 ..... 45616 45617 45618 45619 45620 45621 45622 45623 45624 45625 45626 45627 45628 45629 45630 45631 45632 45633 45634 45635 45636 45637 45638 45639 45640 45641 45642 45643 45644 45645 45646 45647 45648 ..... 45729 45730 45731 45732 45733 45734 45735 45736 45737 45738 45739 45740 45741 45742 ..... 45921 45922 45923 45924 45925 45926 45927 45928 45929 45930 45931 45932 45933 45934 45935 45936 45937 ..... 45944 45945 45946 45947 45948 45949 45950 45951 45952 45953 45954 45955 45956 45957 45958 45959 45960 ..... 46041 46042 46043 46044 46045 46046 46047 46048 46049 46050 46051 46052 46053 46054 46055 46056 46057 46058 46059 46060 46061 46062 46063 46064 46065 46066 46067 46068 46069 46070 ..... 46090 46091 46092 46093 46094 46095 46096 46097 46098 46099 46100 46101 46102 46103 46104 46105 46106 46107 46108 ..... 46143 46144 46145 46146 46147 46148 46149 46150 46151 46152 46153 46154 46155 46156 46157 ..... 46261 46262 46263 46264 46265 46266 46267 46268 46269 46270 46271 46272 46273 46274 ..... 46362 46363 46364 46365 46366 46367 46368 46369 46370 46371 46372 46373 46374 46375 46376 46377 46378 46379 46380 46381 46382 46383 46384 ..... 46389 46390 46391 46392 46393 46394 46395 46396 46397 46398 46399 46400 46401 46402 46403 ..... 46475 46476 46477 46478 46479 46480 46481 46482 46483 46484 46485 46486 46487 46488 46489 ..... 46550 46551 46552 46553 46554 46555 46556 46557 46558 46559 46560 46561 46562 46563 46564 46565 46566 46567 46568 46569 46570 46571 46572 46573 46574 46575 ..... 46705 46706 46707 46708 46709 46710 46711 46712 46713 46714 46715 46716 46717 46718 46719 ..... 46729 46730 46731 46732 46733 46734 46735 46736 46737 46738 46739 46740 46741 46742 46743 46744 46745 46746 ..... 47287 47288 47289 47290 47291 47292 47293 47294 47295 47296 47297 47298 47299 47300 47301 47302 47303 47304 47305 ..... 47524 47525 47526 47527 47528 47529 47530 47531 47532 47533 47534 47535 47536 47537 47538 47539 ..... 48012 48013 48014 48015 48016 48017 48018 48019 48020 48021 48022 48023 48024 48025 48026 48027 48028 48029 48030 48031 48032 48033 48034 48035 48036 48037 ..... 48343 48344 48345 48346 48347 48348 48349 48350 48351 48352 48353 48354 48355 48356 48357 48358 48359 48360 48361 48362 48363 48364 48365 48366 48367 ..... 48564 48565 48566 48567 48568 48569 48570 48571 48572 48573 48574 48575 48576 48577 48578 48579 48580 48581 48582 48583 48584 48585 48586 48587 48588 48589 48590 48591 48592 48593 48594 48595 48596 48597 48598 48599 48600 48601 48602 48603 48604 48605 48606 48607 48608 48609 48610 48611 48612 48613 48614 48615 48616 48617 48618 ..... 48687 48688 48689 48690 48691 48692 48693 48694 48695 48696 48697 48698 48699 48700 ..... 49408 49409 49410 49411 49412 49413 49414 49415 49416 49417 49418 49419 49420 49421 49422 ..... 50176 50177 50178 50179 50180 50181 50182 50183 50184 50185 50186 50187 50188 50189 ..... 50305 50306 50307 50308 50309 50310 50311 50312 50313 50314 50315 50316 50317 50318 ..... 50363 50364 50365 50366 50367 50368 50369 50370 50371 50372 50373 50374 50375 50376 50377 50378 50379 50380 50381 50382 50383 50384 50385 50386 50387 50388 50389 50390 50391 50392 50393 50394 50395 50396 50397 50398 50399 50400 50401 50402 50403 50404 50405 50406 50407 50408 50409 50410 ..... 50416 50417 50418 50419 50420 50421 50422 50423 50424 50425 50426 50427 50428 50429 50430 50431 50432 50433 50434 50435 50436 ..... 50473 50474 50475 50476 50477 50478 50479 50480 50481 50482 50483 50484 50485 50486 50487 50488 50489 50490 50491 ..... 50983 50984 50985 50986 50987 50988 50989 50990 50991 50992 50993 50994 50995 50996 50997 50998 50999 51000 51001 51002 51003 51004 51005 51006 51007 51008 51009 51010 ..... 51495 51496 51497 51498 51499 51500 51501 51502 51503 51504 51505 51506 51507 51508 51509 ..... 51963 51964 51965 51966 51967 51968 51969 51970 51971 51972 51973 51974 51975 51976 ..... 52296 52297 52298 52299 52300 52301 52302 52303 52304 52305 52306 52307 52308 52309 52310 52311 52312 52313 52314 52315 52316 ..... 52722 52723 52724 52725 52726 52727 52728 52729 52730 52731 52732 52733 52734 52735 52736 ..... 52863 52864 52865 52866 52867 52868 52869 52870 52871 52872 52873 52874 52875 52876 52877 52878 52879 52880 52881 52882 52883 52884 ..... 53013 53014 53015 53016 53017 53018 53019 53020 53021 53022 53023 53024 53025 53026 53027 53028 53029 53030 53031 53032 53033 53034 53035 53036 53037 53038 53039 53040 53041 53042 53043 53044 ..... 53743 53744 53745 53746 53747 53748 53749 53750 53751 53752 53753 53754 53755 53756 ..... 53766 53767 53768 53769 53770 53771 53772 53773 53774 53775 53776 53777 53778 53779 53780 53781 53782 53783 53784 53785 53786 53787 53788 53789 53790 53791 53792 53793 53794 53795 53796 53797 53798 53799 53800 53801 53802 53803 53804 53805 53806 ..... 53815 53816 53817 53818 53819 53820 53821 53822 53823 53824 53825 53826 53827 53828 53829 53830 ..... 54717 54718 54719 54720 54721 54722 54723 54724 54725 54726 54727 54728 54729 54730 54731 ..... 54874 54875 54876 54877 54878 54879 54880 54881 54882 54883 54884 54885 54886 54887 54888 ..... 56746 56747 56748 56749 56750 56751 56752 56753 56754 56755 56756 56757 56758 56759 56760 56761 56762 ..... 56789 56790 56791 56792 56793 56794 56795 56796 56797 56798 56799 56800 56801 56802 56803 56804 ..... 57896 57897 57898 57899 57900 57901 57902 57903 57904 57905 57906 57907 57908 57909 57910 57911 ..... 58067 58068 58069 58070 58071 58072 58073 58074 58075 58076 58077 58078 58079 58080 58081 58082 58083 58084 ..... 58145 58146 58147 58148 58149 58150 58151 58152 58153 58154 58155 58156 58157 58158 58159 ..... 58161 58162 58163 58164 58165 58166 58167 58168 58169 58170 58171 58172 58173 58174 58175 ..... 59008 59009 59010 59011 59012 59013 59014 59015 59016 59017 59018 59019 59020 59021 59022 59023 59024 59025 59026 59027 59028 59029 59030 59031 59032 59033 59034 59035 59036 59037 59038 59039 59040 59041 59042 59043 59044 59045 ..... 59947 59948 59949 59950 59951 59952 59953 59954 59955 59956 59957 59958 59959 59960 59961 ..... 60106 60107 60108 60109 60110 60111 60112 60113 60114 60115 60116 60117 60118 60119 60120 60121 60122 60123 60124 ..... 60239 60240 60241 60242 60243 60244 60245 60246 60247 60248 60249 60250 60251 60252 60253 ..... 60279 60280 60281 60282 60283 60284 60285 60286 60287 60288 60289 60290 60291 60292 60293 ..... 60342 60343 60344 60345 60346 60347 60348 60349 60350 60351 60352 60353 60354 60355 ..... 60892 60893 60894 60895 60896 60897 60898 60899 60900 60901 60902 60903 60904 60905 60906 60907 ..... 60982 60983 60984 60985 60986 60987 60988 60989 60990 60991 60992 60993 60994 60995 60996 60997 60998 60999 61000 61001 61002 61003 61004 61005 61006 61007 61008 61009 61010 61011 61012 61013 ..... 61020 61021 61022 61023 61024 61025 61026 61027 61028 61029 61030 61031 61032 61033 61034 ..... 61134 61135 61136 61137 61138 61139 61140 61141 61142 61143 61144 61145 61146 61147 61148 61149 61150 61151 61152 61153 61154 61155 61156 61157 61158 61159 61160 61161 61162 61163 61164 ..... 61167 61168 61169 61170 61171 61172 61173 61174 61175 61176 61177 61178 61179 61180 61181 ..... 61203 61204 61205 61206 61207 61208 61209 61210 61211 61212 61213 61214 61215 61216 61217 61218 61219 61220 61221 61222 61223 61224 61225 61226 61227 61228 61229 ..... 61530 61531 61532 61533 61534 61535 61536 61537 61538 61539 61540 61541 61542 61543 61544 ..... 61557 61558 61559 61560 61561 61562 61563 61564 61565 61566 61567 61568 61569 61570 61571 ..... 61591 61592 61593 61594 61595 61596 61597 61598 61599 61600 61601 61602 61603 61604 61605 61606 61607 61608 61609 61610 61611 61612 61613 61614 61615 61616 61617 61618 61619 61620 61621 61622 61623 61624 61625 ..... 62397 62398 62399 62400 62401 62402 62403 62404 62405 62406 62407 62408 62409 62410 62411 ..... 62491 62492 62493 62494 62495 62496 62497 62498 62499 62500 62501 62502 62503 62504 62505 ..... 62538 62539 62540 62541 62542 62543 62544 62545 62546 62547 62548 62549 62550 62551 62552 ..... 62592 62593 62594 62595 62596 62597 62598 62599 62600 62601 62602 62603 62604 62605 62606 ..... 62637 62638 62639 62640 62641 62642 62643 62644 62645 62646 62647 62648 62649 62650 62651 ..... 63489 63490 63491 63492 63493 63494 63495 63496 63497 63498 63499 63500 63501 63502 63503 63504 63505 63506 63507 63508 63509 63510 63511 63512 63513 63514 63515 63516 63517 63518 63519 63520 ..... 63563 63564 63565 63566 63567 63568 63569 63570 63571 63572 63573 63574 63575 63576 63577 ..... 63805 63806 63807 63808 63809 63810 63811 63812 63813 63814 63815 63816 63817 63818 63819 63820 63821 63822 63823 63824 63825 63826 63827 63828 63829 63830 63831 63832 63833 63834 63835 63836 63837 63838 63839 63840 63841 ..... 63844 63845 63846 63847 63848 63849 63850 63851 63852 63853 63854 63855 63856 63857 63858 63859 63860 63861 63862 63863 63864 63865 63866 63867 63868 63869 63870 ..... 64054 64055 64056 64057 64058 64059 64060 64061 64062 64063 64064 64065 64066 64067 64068 ..... 64250 64251 64252 64253 64254 64255 64256 64257 64258 64259 64260 64261 64262 64263 64264 64265 ..... 64308 64309 64310 64311 64312 64313 64314 64315 64316 64317 64318 64319 64320 64321 64322 64323 64324 64325 64326 64327 64328 64329 64330 64331 64332 64333 ..... 64364 64365 64366 64367 64368 64369 64370 64371 64372 64373 64374 64375 64376 64377 64378 64379 64380 64381 ..... 64401 64402 64403 64404 64405 64406 64407 64408 64409 64410 64411 64412 64413 64414 64415 64416 64417 64418 64419 64420 64421 64422 64423 64424 64425 64426 64427 64428 64429 64430 64431 64432 64433 64434 64435 64436 64437 64438 64439 64440 64441 64442 ..... 64446 64447 64448 64449 64450 64451 64452 64453 64454 64455 64456 64457 64458 64459 64460 64461 64462 64463 64464 64465 64466 64467 64468 64469 64470 64471 64472 64473 64474 64475 64476 64477 64478 64479 64480 64481 64482 64483 64484 64485 64486 64487 64488 64489 64490 ..... 64491 64492 64493 64494 64495 64496 64497 64498 64499 64500 64501 64502 64503 64504 64505 64506 64507 64508 64509 64510 64511 64512 64513 64514 64515 64516 64517 64518 64519 64520 64521 64522 64523 ..... 64528 64529 64530 64531 64532 64533 64534 64535 64536 64537 64538 64539 64540 64541 64542 ..... 64553 64554 64555 64556 64557 64558 64559 64560 64561 64562 64563 64564 64565 64566 64567 ..... 64576 64577 64578 64579 64580 64581 64582 64583 64584 64585 64586 64587 64588 64589 64590 64591 64592 64593 64594 64595 64596 64597 ..... 64607 64608 64609 64610 64611 64612 64613 64614 64615 64616 64617 64618 64619 64620 64621 64622 64623 64624 64625 64626 64627 64628 64629 64630 64631 64632 64633 64634 64635 64636 64637 64638 64639 64640 64641 64642 ..... 64727 64728 64729 64730 64731 64732 64733 64734 64735 64736 64737 64738 64739 64740 64741 64742 64743 64744 64745 64746 64747 64748 64749 64750 64751 64752 64753 64754 64755 64756 ..... 64870 64871 64872 64873 64874 64875 64876 64877 64878 64879 64880 64881 64882 64883 64884 64885 64886 64887 64888 64889 64890 64891 64892 64893 64894 64895 ..... 64935 64936 64937 64938 64939 64940 64941 64942 64943 64944 64945 64946 64947 64948 64949 64950 64951 ..... 64990 64991 64992 64993 64994 64995 64996 64997 64998 64999 65000 65001 65002 65003 65004 ..... 65013 65014 65015 65016 65017 65018 65019 65020 65021 65022 65023 65024 65025 65026 65027 ..... 65036 65037 65038 65039 65040 65041 65042 65043 65044 65045 65046 65047 65048 65049 65050 ..... 65095 65096 65097 65098 65099 65100 65101 65102 65103 65104 65105 65106 65107 65108 65109 ..... 65114 65115 65116 65117 65118 65119 65120 65121 65122 65123 65124 65125 65126 65127 65128 ..... 65132 65133 65134 65135 65136 65137 65138 65139 65140 65141 65142 65143 65144 65145 65146 ..... 65628 65629 65630 65631 65632 65633 65634 65635 65636 65637 65638 65639 65640 65641 65642 ..... 65644 65645 65646 65647 65648 65649 65650 65651 65652 65653 65654 65655 65656 65657 ..... 65711 65712 65713 65714 65715 65716 65717 65718 65719 65720 65721 65722 65723 65724 65725 65726 65727 65728 65729 65730 65731 65732 65733 65734 65735 65736 65737 65738 65739 ..... 65745 65746 65747 65748 65749 65750 65751 65752 65753 65754 65755 65756 65757 65758 65759 65760 65761 65762 65763 65764 65765 65766 65767 65768 65769 65770 65771 65772 65773 65774 65775 65776 65777 ..... 65789 65790 65791 65792 65793 65794 65795 65796 65797 65798 65799 65800 65801 65802 65803 65804 ..... 65843 65844 65845 65846 65847 65848 65849 65850 65851 65852 65853 65854 65855 65856 65857 65858 65859 65860 65861 65862 65863 65864 65865 65866 65867 65868 65869 65870 65871 65872 65873 65874 65875 65876 65877 65878 65879 65880 ..... 65898 65899 65900 65901 65902 65903 65904 65905 65906 65907 65908 65909 65910 65911 65912 ..... 66765 66766 66767 66768 66769 66770 66771 66772 66773 66774 66775 66776 66777 66778 66779 66780 66781 66782 ..... 67346 67347 67348 67349 67350 67351 67352 67353 67354 67355 67356 67357 67358 67359 67360 ..... 67445 67446 67447 67448 67449 67450 67451 67452 67453 67454 67455 67456 67457 67458 67459 ..... 67461 67462 67463 67464 67465 67466 67467 67468 67469 67470 67471 67472 67473 67474 67475 ..... 67541 67542 67543 67544 67545 67546 67547 67548 67549 67550 67551 67552 67553 67554 ..... 67672 67673 67674 67675 67676 67677 67678 67679 67680 67681 67682 67683 67684 67685 67686 ..... 67759 67760 67761 67762 67763 67764 67765 67766 67767 67768 67769 67770 67771 67772 67773 67774 67775 67776 67777 67778 67779 67780 67781 67782 67783 67784 67785 67786 67787 67788 67789 67790 ..... 67817 67818 67819 67820 67821 67822 67823 67824 67825 67826 67827 67828 67829 67830 67831 67832 67833 67834 67835 67836 67837 ..... 67889 67890 67891 67892 67893 67894 67895 67896 67897 67898 67899 67900 67901 67902 67903 67904 67905 67906 67907 ..... 67925 67926 67927 67928 67929 67930 67931 67932 67933 67934 67935 67936 67937 67938 67939 67940 67941 67942 67943 67944 67945 67946 67947 67948 67949 67950 67951 67952 67953 67954 67955 67956 67957 67958 67959 67960 67961 ..... 68412 68413 68414 68415 68416 68417 68418 68419 68420 68421 68422 68423 68424 68425 68426 68427 68428 68429 68430 68431 68432 68433 68434 68435 68436 68437 68438 68439 68440 68441 68442 68443 ..... 68452 68453 68454 68455 68456 68457 68458 68459 68460 68461 68462 68463 68464 68465 68466 68467 68468 68469 ..... 69296 69297 69298 69299 69300 69301 69302 69303 69304 69305 69306 69307 69308 69309 69310 ..... 70219 70220 70221 70222 70223 70224 70225 70226 70227 70228 70229 70230 70231 70232 70233 70234 70235 70236 70237 70238 70239 70240 70241 70242 70243 70244 70245 70246 70247 70248 ..... 70322 70323 70324 70325 70326 70327 70328 70329 70330 70331 70332 70333 70334 70335 70336 ..... 70338 70339 70340 70341 70342 70343 70344 70345 70346 70347 70348 70349 70350 70351 70352 ..... 70375 70376 70377 70378 70379 70380 70381 70382 70383 70384 70385 70386 70387 70388 70389 70390 70391 70392 70393 70394 70395 70396 70397 70398 70399 70400 70401 70402 70403 70404 70405 70406 70407 ..... 70432 70433 70434 70435 70436 70437 70438 70439 70440 70441 70442 70443 70444 70445 70446 70447 70448 70449 70450 70451 70452 70453 70454 70455 70456 70457 70458 70459 ..... 70764 70765 70766 70767 70768 70769 70770 70771 70772 70773 70774 70775 70776 70777 70778 70779 70780 70781 70782 70783 70784 70785 ..... 70896 70897 70898 70899 70900 70901 70902 70903 70904 70905 70906 70907 70908 70909 ..... 71077 71078 71079 71080 71081 71082 71083 71084 71085 71086 71087 71088 71089 71090 71091 ..... 71155 71156 71157 71158 71159 71160 71161 71162 71163 71164 71165 71166 71167 71168 71169 71170 71171 71172 71173 71174 ..... 71309 71310 71311 71312 71313 71314 71315 71316 71317 71318 71319 71320 71321 71322 71323 ..... 71845 71846 71847 71848 71849 71850 71851 71852 71853 71854 71855 71856 71857 71858 71859 ..... 71941 71942 71943 71944 71945 71946 71947 71948 71949 71950 71951 71952 71953 71954 71955 71956 71957 71958 ..... 72398 72399 72400 72401 72402 72403 72404 72405 72406 72407 72408 72409 72410 72411 72412 ..... 72426 72427 72428 72429 72430 72431 72432 72433 72434 72435 72436 72437 72438 72439 72440 ..... 72504 72505 72506 72507 72508 72509 72510 72511 72512 72513 72514 72515 72516 72517 72518 72519 72520 72521 72522 72523 72524 72525 72526 72527 72528 72529 72530 72531 72532 72533 72534 72535 72536 72537 72538 72539 72540 72541 72542 72543 72544 72545 72546 72547 72548 72549 72550 ..... 72794 72795 72796 72797 72798 72799 72800 72801 72802 72803 72804 72805 72806 72807 72808 ..... 73209 73210 73211 73212 73213 73214 73215 73216 73217 73218 73219 73220 73221 73222 73223 73224 ..... 73282 73283 73284 73285 73286 73287 73288 73289 73290 73291 73292 73293 73294 73295 73296 ..... 74046 74047 74048 74049 74050 74051 74052 74053 74054 74055 74056 74057 74058 74059 74060 74061 74062 74063 74064 74065 74066 74067 74068 74069 74070 74071 74072 74073 74074 74075 74076 74077 74078 74079 74080 ..... 74775 74776 74777 74778 74779 74780 74781 74782 74783 74784 74785 74786 74787 74788 ..... 74792 74793 74794 74795 74796 74797 74798 74799 74800 74801 74802 74803 74804 74805 74806 74807 74808 74809 74810 74811 74812 74813 74814 74815 74816 74817 74818 74819 74820 74821 74822 74823 74824 74825 74826 74827 74828 74829 ..... 75028 75029 75030 75031 75032 75033 75034 75035 75036 75037 75038 75039 75040 75041 75042 75043 75044 75045 75046 75047 75048 75049 75050 75051 75052 75053 75054 ..... 75436 75437 75438 75439 75440 75441 75442 75443 75444 75445 75446 75447 75448 75449 75450 75451 75452 75453 75454 75455 75456 ..... 75482 75483 75484 75485 75486 75487 75488 75489 75490 75491 75492 75493 75494 75495 75496 ..... 75531 75532 75533 75534 75535 75536 75537 75538 75539 75540 75541 75542 75543 75544 75545 75546 75547 ..... 75595 75596 75597 75598 75599 75600 75601 75602 75603 75604 75605 75606 75607 75608 75609 75610 75611 75612 75613 75614 ..... 75621 75622 75623 75624 75625 75626 75627 75628 75629 75630 75631 75632 75633 75634 75635 ..... 75926 75927 75928 75929 75930 75931 75932 75933 75934 75935 75936 75937 75938 75939 75940 75941 75942 75943 ..... 76262 76263 76264 76265 76266 76267 76268 76269 76270 76271 76272 76273 76274 76275 76276 ..... 76490 76491 76492 76493 76494 76495 76496 76497 76498 76499 76500 76501 76502 76503 ..... 76575 76576 76577 76578 76579 76580 76581 76582 76583 76584 76585 76586 76587 76588 76589 76590 76591 76592 76593 76594 76595 76596 76597 76598 76599 76600 ..... 76799 76800 76801 76802 76803 76804 76805 76806 76807 76808 76809 76810 76811 76812 ..... 76978 76979 76980 76981 76982 76983 76984 76985 76986 76987 76988 76989 76990 76991 ..... 77100 77101 77102 77103 77104 77105 77106 77107 77108 77109 77110 77111 77112 77113 77114 ..... 77210 77211 77212 77213 77214 77215 77216 77217 77218 77219 77220 77221 77222 77223 77224 ..... 77254 77255 77256 77257 77258 77259 77260 77261 77262 77263 77264 77265 77266 77267 77268 77269 77270 77271 77272 77273 77274 77275 77276 77277 77278 77279 77280 77281 77282 77283 77284 77285 77286 77287 77288 77289 77290 77291 77292 77293 77294 77295 77296 77297 77298 77299 77300 77301 77302 77303 77304 77305 77306 77307 ..... 77980 77981 77982 77983 77984 77985 77986 77987 77988 77989 77990 77991 77992 77993 ..... 78281 78282 78283 78284 78285 78286 78287 78288 78289 78290 78291 78292 78293 78294 78295 ..... 78354 78355 78356 78357 78358 78359 78360 78361 78362 78363 78364 78365 78366 78367 78368 ..... 78607 78608 78609 78610 78611 78612 78613 78614 78615 78616 78617 78618 78619 78620 78621 ..... 79076 79077 79078 79079 79080 79081 79082 79083 79084 79085 79086 79087 79088 79089 79090 ..... 80401 80402 80403 80404 80405 80406 80407 80408 80409 80410 80411 80412 80413 80414 80415 80416 80417 80418 80419 80420 80421 80422 80423 80424 80425 80426 80427 80428 80429 80430 80431 80432 80433 80434 80435 80436 80437 80438 80439 80440 80441 80442 80443 80444 80445 80446 80447 80448 80449 80450 80451 80452 80453 80454 80455 80456 80457 80458 80459 80460 80461 80462 80463 80464 80465 80466 80467 80468 80469 80470 80471 80472 80473 80474 80475 80476 80477 80478 80479 80480 80481 80482 80483 80484 80485 80486 80487 80488 80489 80490 80491 80492 80493 80494 80495 80496 80497 80498 80499 80500 80501 80502 80503 80504 80505 80506 80507 80508 80509 80510 80511 80512 80513 80514 80515 80516 80517 80518 80519 80520 80521 80522 80523 80524 80525 ..... 80877 80878 80879 80880 80881 80882 80883 80884 80885 80886 80887 80888 80889 80890 80891 80892 80893 80894 80895 80896 80897 80898 80899 80900 80901 80902 80903 80904 80905 80906 80907 80908 80909 ..... 81026 81027 81028 81029 81030 81031 81032 81033 81034 81035 81036 81037 81038 81039 81040 ..... 81299 81300 81301 81302 81303 81304 81305 81306 81307 81308 81309 81310 81311 81312 81313 81314 81315 ..... 81328 81329 81330 81331 81332 81333 81334 81335 81336 81337 81338 81339 81340 81341 81342 81343 81344 81345 81346 81347 81348 81349 81350 81351 81352 81353 81354 81355 81356 81357 81358 81359 81360 81361 81362 81363 81364 81365 81366 81367 81368 81369 81370 81371 81372 81373 81374 ..... 81377 81378 81379 81380 81381 81382 81383 81384 81385 81386 81387 81388 81389 81390 81391 81392 81393 81394 81395 81396 81397 81398 81399 81400 81401 ..... 81416 81417 81418 81419 81420 81421 81422 81423 81424 81425 81426 81427 81428 81429 ..... 81436 81437 81438 81439 81440 81441 81442 81443 81444 81445 81446 81447 81448 81449 81450 81451 81452 ..... 81532 81533 81534 81535 81536 81537 81538 81539 81540 81541 81542 81543 81544 81545 ..... 81872 81873 81874 81875 81876 81877 81878 81879 81880 81881 81882 81883 81884 81885 81886 ..... 81891 81892 81893 81894 81895 81896 81897 81898 81899 81900 81901 81902 81903 81904 81905 ..... 82171 82172 82173 82174 82175 82176 82177 82178 82179 82180 82181 82182 82183 82184 82185 ..... 82310 82311 82312 82313 82314 82315 82316 82317 82318 82319 82320 82321 82322 82323 82324 82325 82326 82327 82328 82329 82330 82331 82332 82333 82334 ..... 82531 82532 82533 82534 82535 82536 82537 82538 82539 82540 82541 82542 82543 82544 82545 82546 ..... 83324 83325 83326 83327 83328 83329 83330 83331 83332 83333 83334 83335 83336 83337 83338 83339 83340 83341 83342 83343 83344 83345 ..... 83698 83699 83700 83701 83702 83703 83704 83705 83706 83707 83708 83709 83710 83711 83712 83713 83714 83715 83716 83717 83718 83719 83720 83721 83722 83723 83724 83725 83726 83727 83728 83729 83730 83731 83732 83733 83734 83735 83736 83737 83738 83739 83740 83741 83742 83743 83744 83745 83746 83747 83748 83749 83750 83751 83752 83753 83754 83755 83756 83757 83758 ..... 84373 84374 84375 84376 84377 84378 84379 84380 84381 84382 84383 84384 84385 84386 84387 84388 84389 84390 84391 84392 84393 84394 84395 84396 84397 84398 84399 84400 84401 84402 84403 84404 84405 84406 84407 84408 84409 84410 84411 84412 84413 84414 84415 84416 84417 84418 84419 84420 84421 84422 84423 84424 84425 84426 84427 84428 84429 84430 ..... 84578 84579 84580 84581 84582 84583 84584 84585 84586 84587 84588 84589 84590 84591 84592 84593 84594 84595 84596 84597 84598 84599 84600 ..... 85811 85812 85813 85814 85815 85816 85817 85818 85819 85820 85821 85822 85823 85824 85825 85826 85827 85828 85829 85830 85831 85832 85833 85834 85835 85836 85837 85838 85839 ..... 86100 86101 86102 86103 86104 86105 86106 86107 86108 86109 86110 86111 86112 86113 86114 86115 86116 86117 86118 ..... 86166 86167 86168 86169 86170 86171 86172 86173 86174 86175 86176 86177 86178 86179 86180 86181 ..... 86185 86186 86187 86188 86189 86190 86191 86192 86193 86194 86195 86196 86197 86198 86199 86200 86201 86202 86203 86204 86205 86206 86207 86208 86209 86210 86211 86212 86213 86214 86215 86216 86217 86218 86219 86220 86221 86222 86223 86224 86225 86226 86227 86228 86229 ..... 86279 86280 86281 86282 86283 86284 86285 86286 86287 86288 86289 86290 86291 86292 86293 ..... 86315 86316 86317 86318 86319 86320 86321 86322 86323 86324 86325 86326 86327 86328 86329 ..... 86330 86331 86332 86333 86334 86335 86336 86337 86338 86339 86340 86341 86342 86343 86344 ..... 86352 86353 86354 86355 86356 86357 86358 86359 86360 86361 86362 86363 86364 86365 86366 86367 86368 86369 ..... 86377 86378 86379 86380 86381 86382 86383 86384 86385 86386 86387 86388 86389 86390 86391 86392 ..... 87372 87373 87374 87375 87376 87377 87378 87379 87380 87381 87382 87383 87384 87385 87386 ..... 87441 87442 87443 87444 87445 87446 87447 87448 87449 87450 87451 87452 87453 87454 87455 ..... 87456 87457 87458 87459 87460 87461 87462 87463 87464 87465 87466 87467 87468 87469 87470 ..... 87509 87510 87511 87512 87513 87514 87515 87516 87517 87518 87519 87520 87521 87522 87523 87524 87525 87526 87527 87528 87529 87530 87531 87532 87533 87534 87535 87536 ..... 87550 87551 87552 87553 87554 87555 87556 87557 87558 87559 87560 87561 87562 87563 87564 87565 87566 87567 87568 87569 87570 87571 87572 87573 87574 87575 87576 ..... 87877 87878 87879 87880 87881 87882 87883 87884 87885 87886 87887 87888 87889 87890 87891 ..... 89401 89402 89403 89404 89405 89406 89407 89408 89409 89410 89411 89412 89413 89414 89415 ..... 89520 89521 89522 89523 89524 89525 89526 89527 89528 89529 89530 89531 89532 89533 89534 ..... 89689 89690 89691 89692 89693 89694 89695 89696 89697 89698 89699 89700 89701 89702 89703 89704 89705 89706 89707 89708 89709 89710 89711 89712 89713 ..... 89766 89767 89768 89769 89770 89771 89772 89773 89774 89775 89776 89777 89778 89779 89780 89781 89782 89783 89784 89785 89786 89787 89788 89789 89790 89791 ..... 90845 90846 90847 90848 90849 90850 90851 90852 90853 90854 90855 90856 90857 90858 90859 90860 90861 90862 90863 90864 ..... 90942 90943 90944 90945 90946 90947 90948 90949 90950 90951 90952 90953 90954 90955 90956 90957 90958 90959 90960 90961 ..... 91548 91549 91550 91551 91552 91553 91554 91555 91556 91557 91558 91559 91560 91561 ..... 91611 91612 91613 91614 91615 91616 91617 91618 91619 91620 91621 91622 91623 91624 ..... 92199 92200 92201 92202 92203 92204 92205 92206 92207 92208 92209 92210 92211 92212 92213 ..... 92726 92727 92728 92729 92730 92731 92732 92733 92734 92735 92736 92737 92738 92739 92740 92741 92742 92743 ..... 92883 92884 92885 92886 92887 92888 92889 92890 92891 92892 92893 92894 92895 92896 ..... 92901 92902 92903 92904 92905 92906 92907 92908 92909 92910 92911 92912 92913 92914 92915 92916 92917 92918 92919 92920 92921 92922 92923 92924 ..... 93101 93102 93103 93104 93105 93106 93107 93108 93109 93110 93111 93112 93113 93114 93115 93116 93117 93118 93119 93120 93121 93122 93123 ..... 93187 93188 93189 93190 93191 93192 93193 93194 93195 93196 93197 93198 93199 93200 93201 93202 93203 93204 93205 93206 93207 93208 93209 93210 93211 93212 93213 93214 93215 ..... 93255 93256 93257 93258 93259 93260 93261 93262 93263 93264 93265 93266 93267 93268 93269 93270 ..... 93324 93325 93326 93327 93328 93329 93330 93331 93332 93333 93334 93335 93336 93337 93338 ..... 93397 93398 93399 93400 93401 93402 93403 93404 93405 93406 93407 93408 93409 93410 93411 93412 ..... 94060 94061 94062 94063 94064 94065 94066 94067 94068 94069 94070 94071 94072 94073 94074 ..... 94488 94489 94490 94491 94492 94493 94494 94495 94496 94497 94498 94499 94500 94501 94502 94503 94504 94505 94506 94507 94508 94509 94510 94511 94512 94513 94514 94515 94516 ..... 94662 94663 94664 94665 94666 94667 94668 94669 94670 94671 94672 94673 94674 94675 94676 94677 ..... 94907 94908 94909 94910 94911 94912 94913 94914 94915 94916 94917 94918 94919 94920 94921 94922 94923 94924 94925 94926 94927 ..... 95250 95251 95252 95253 95254 95255 95256 95257 95258 95259 95260 95261 95262 95263 95264 95265 ..... 95656 95657 95658 95659 95660 95661 95662 95663 95664 95665 95666 95667 95668 95669 95670 95671 95672 95673 95674 95675 95676 95677 95678 95679 95680 ..... 96679 96680 96681 96682 96683 96684 96685 96686 96687 96688 96689 96690 96691 96692 96693 96694 ..... 97100 97101 97102 97103 97104 97105 97106 97107 97108 97109 97110 97111 97112 97113 97114 97115 97116 97117 97118 97119 97120 97121 97122 97123 97124 97125 ..... 97276 97277 97278 97279 97280 97281 97282 97283 97284 97285 97286 97287 97288 97289 97290 ..... 97377 97378 97379 97380 97381 97382 97383 97384 97385 97386 97387 97388 97389 97390 97391 97392 97393 97394 97395 97396 97397 97398 97399 97400 97401 97402 97403 97404 ..... 99515 99516 99517 99518 99519 99520 99521 99522 99523 99524 99525 99526 99527 99528 99529 99530 99531 99532 ..... 99710 99711 99712 99713 99714 99715 99716 99717 99718 99719 99720 99721 99722 99723 99724 99725 99726 99727 99728 ...... 100127 100128 100129 100130 100131 100132 100133 100134 100135 100136 100137 100138 100139 100140 100141 100142 100143 100144 100145 ...... 100764 100765 100766 100767 100768 100769 100770 100771 100772 100773 100774 100775 100776 100777 100778 ...... 100799 100800 100801 100802 100803 100804 100805 100806 100807 100808 100809 100810 100811 100812 100813 100814 100815 100816 100817 100818 100819 100820 100821 100822 100823 100824 100825 100826 100827 100828 100829 100830 100831 100832 100833 100834 100835 100836 100837 100838 100839 100840 100841 100842 100843 100844 100845 100846 100847 100848 100849 100850 100851 100852 100853 100854 100855 100856 100857 100858 100859 100860 ...... 100884 100885 100886 100887 100888 100889 100890 100891 100892 100893 100894 100895 100896 100897 100898 100899 100900 100901 100902 100903 100904 ...... 100924 100925 100926 100927 100928 100929 100930 100931 100932 100933 100934 100935 100936 100937 100938 ...... 100950 100951 100952 100953 100954 100955 100956 100957 100958 100959 100960 100961 100962 100963 100964 ...... 101063 101064 101065 101066 101067 101068 101069 101070 101071 101072 101073 101074 101075 101076 101077 ...... 101295 101296 101297 101298 101299 101300 101301 101302 101303 101304 101305 101306 101307 101308 101309 ...... 101344 101345 101346 101347 101348 101349 101350 101351 101352 101353 101354 101355 101356 101357 101358 101359 101360 101361 101362 101363 ...... 101955 101956 101957 101958 101959 101960 101961 101962 101963 101964 101965 101966 101967 101968 101969 101970 101971 101972 101973 101974 101975 101976 101977 101978 101979 ...... 101994 101995 101996 101997 101998 101999 102000 102001 102002 102003 102004 102005 102006 102007 102008 102009 102010 102011 102012 102013 102014 ...... 102023 102024 102025 102026 102027 102028 102029 102030 102031 102032 102033 102034 102035 102036 102037 102038 102039 102040 102041 102042 102043 102044 102045 ...... 102050 102051 102052 102053 102054 102055 102056 102057 102058 102059 102060 102061 102062 102063 ...... 102340 102341 102342 102343 102344 102345 102346 102347 102348 102349 102350 102351 102352 102353 102354 ...... 102439 102440 102441 102442 102443 102444 102445 102446 102447 102448 102449 102450 102451 102452 102453 102454 102455 102456 102457 102458 102459 102460 102461 ...... 102643 102644 102645 102646 102647 102648 102649 102650 102651 102652 102653 102654 102655 102656 102657 102658 102659 102660 102661 102662 102663 102664 ...... 102693 102694 102695 102696 102697 102698 102699 102700 102701 102702 102703 102704 102705 102706 102707 ...... 103120 103121 103122 103123 103124 103125 103126 103127 103128 103129 103130 103131 103132 103133 103134 ...... 103609 103610 103611 103612 103613 103614 103615 103616 103617 103618 103619 103620 103621 103622 103623 ...... 103645 103646 103647 103648 103649 103650 103651 103652 103653 103654 103655 103656 103657 103658 103659 ...... 104167 104168 104169 104170 104171 104172 104173 104174 104175 104176 104177 104178 104179 104180 104181 104182 104183 104184 104185 104186 104187 104188 104189 104190 104191 104192 ...... 105103 105104 105105 105106 105107 105108 105109 105110 105111 105112 105113 105114 105115 105116 105117 105118 105119 105120 105121 105122 105123 105124 105125 105126 105127 ...... 105186 105187 105188 105189 105190 105191 105192 105193 105194 105195 105196 105197 105198 105199 105200 105201 ...... 105719 105720 105721 105722 105723 105724 105725 105726 105727 105728 105729 105730 105731 105732 105733 ...... 106069 106070 106071 106072 106073 106074 106075 106076 106077 106078 106079 106080 106081 106082 106083 106084 106085 106086 ...... 106209 106210 106211 106212 106213 106214 106215 106216 106217 106218 106219 106220 106221 106222 ...... 106985 106986 106987 106988 106989 106990 106991 106992 106993 106994 106995 106996 106997 106998 106999 ...... 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 107859 107860 107861 ...... 109647 109648 109649 109650 109651 109652 109653 109654 109655 109656 109657 109658 109659 109660 109661 ...... 109905 109906 109907 109908 109909 109910 109911 109912 109913 109914 109915 109916 109917 109918 109919 ...... 109961 109962 109963 109964 109965 109966 109967 109968 109969 109970 109971 109972 109973 109974 109975 109976 ...... 110754 110755 110756 110757 110758 110759 110760 110761 110762 110763 110764 110765 110766 110767 110768 ...... 110774 110775 110776 110777 110778 110779 110780 110781 110782 110783 110784 110785 110786 110787 ...... 110918 110919 110920 110921 110922 110923 110924 110925 110926 110927 110928 110929 110930 110931 110932 110933 110934 110935 110936 110937 110938 110939 110940 110941 110942 110943 110944 110945 110946 110947 110948 ...... 111479 111480 111481 111482 111483 111484 111485 111486 111487 111488 111489 111490 111491 111492 111493 ...... 111555 111556 111557 111558 111559 111560 111561 111562 111563 111564 111565 111566 111567 111568 111569 111570 111571 111572 111573 111574 111575 111576 111577 ...... 111599 111600 111601 111602 111603 111604 111605 111606 111607 111608 111609 111610 111611 111612 111613 111614 ...... 111631 111632 111633 111634 111635 111636 111637 111638 111639 111640 111641 111642 111643 111644 111645 111646 111647 111648 111649 111650 111651 ...... 111652 111653 111654 111655 111656 111657 111658 111659 111660 111661 111662 111663 111664 111665 111666 ...... 111983 111984 111985 111986 111987 111988 111989 111990 111991 111992 111993 111994 111995 111996 111997 ...... 112095 112096 112097 112098 112099 112100 112101 112102 112103 112104 112105 112106 112107 112108 112109 ...... 112138 112139 112140 112141 112142 112143 112144 112145 112146 112147 112148 112149 112150 112151 ...... 112264 112265 112266 112267 112268 112269 112270 112271 112272 112273 112274 112275 112276 112277 112278 ...... 112288 112289 112290 112291 112292 112293 112294 112295 112296 112297 112298 112299 112300 112301 112302 ...... 112364 112365 112366 112367 112368 112369 112370 112371 112372 112373 112374 112375 112376 112377 112378 ...... 112401 112402 112403 112404 112405 112406 112407 112408 112409 112410 112411 112412 112413 112414 ...... 112832 112833 112834 112835 112836 112837 112838 112839 112840 112841 112842 112843 112844 112845 112846 ...... 114153 114154 114155 114156 114157 114158 114159 114160 114161 114162 114163 114164 114165 114166 114167 114168 114169 114170 114171 114172 114173 114174 114175 114176 ...... 115089 115090 115091 115092 115093 115094 115095 115096 115097 115098 115099 115100 115101 115102 115103 115104 115105 115106 115107 115108 115109 115110 115111 115112 115113 115114 115115 115116 115117 115118 115119 115120 115121 115122 115123 115124 115125 115126 115127 115128 115129 115130 115131 ...... 115343 115344 115345 115346 115347 115348 115349 115350 115351 115352 115353 115354 115355 115356 115357 115358 115359 115360 115361 115362 ...... 115363 115364 115365 115366 115367 115368 115369 115370 115371 115372 115373 115374 115375 115376 115377 115378 115379 115380 115381 115382 115383 115384 115385 115386 115387 115388 115389 115390 115391 115392 115393 115394 115395 115396 115397 115398 115399 115400 115401 115402 115403 115404 115405 115406 115407 115408 115409 115410 115411 115412 115413 115414 115415 115416 115417 115418 115419 115420 115421 115422 115423 115424 115425 115426 115427 115428 115429 115430 ...... 115437 115438 115439 115440 115441 115442 115443 115444 115445 115446 115447 115448 115449 115450 115451 115452 115453 115454 115455 115456 115457 115458 115459 115460 115461 115462 115463 115464 115465 115466 115467 115468 115469 115470 115471 115472 115473 115474 115475 115476 115477 115478 115479 115480 115481 115482 115483 115484 115485 115486 115487 115488 115489 115490 115491 115492 115493 115494 115495 115496 115497 115498 115499 115500 115501 115502 115503 115504 115505 115506 115507 115508 115509 115510 115511 115512 115513 115514 115515 115516 115517 115518 115519 115520 115521 115522 115523 115524 115525 115526 115527 115528 115529 115530 115531 115532 115533 115534 115535 115536 115537 115538 115539 115540 115541 115542 115543 115544 115545 115546 115547 115548 115549 115550 115551 115552 115553 115554 115555 115556 115557 115558 115559 ...... 115797 115798 115799 115800 115801 115802 115803 115804 115805 115806 115807 115808 115809 115810 115811 ...... 116224 116225 116226 116227 116228 116229 116230 116231 116232 116233 116234 116235 116236 116237 116238 116239 116240 116241 ...... 116420 116421 116422 116423 116424 116425 116426 116427 116428 116429 116430 116431 116432 116433 116434 ...... 116484 116485 116486 116487 116488 116489 116490 116491 116492 116493 116494 116495 116496 116497 116498 116499 116500 116501 116502 116503 116504 116505 116506 116507 ...... 116509 116510 116511 116512 116513 116514 116515 116516 116517 116518 116519 116520 116521 116522 116523 116524 116525 116526 ...... 116671 116672 116673 116674 116675 116676 116677 116678 116679 116680 116681 116682 116683 116684 116685 116686 116687 ...... 116689 116690 116691 116692 116693 116694 116695 116696 116697 116698 116699 116700 116701 116702 116703 116704 116705 116706 116707 116708 116709 116710 116711 116712 116713 116714 116715 116716 116717 116718 116719 116720 116721 116722 116723 116724 116725 116726 116727 116728 116729 116730 116731 116732 116733 116734 116735 116736 116737 116738 ...... 116829 116830 116831 116832 116833 116834 116835 116836 116837 116838 116839 116840 116841 116842 116843 116844 116845 116846 116847 116848 116849 116850 116851 116852 ...... 117024 117025 117026 117027 117028 117029 117030 117031 117032 117033 117034 117035 117036 117037 ...... 117100 117101 117102 117103 117104 117105 117106 117107 117108 117109 117110 117111 117112 117113 117114 117115 117116 117117 117118 117119 117120 117121 117122 117123 117124 117125 117126 117127 117128 117129 117130 117131 ...... 117305 117306 117307 117308 117309 117310 117311 117312 117313 117314 117315 117316 117317 117318 117319 ...... 117348 117349 117350 117351 117352 117353 117354 117355 117356 117357 117358 117359 117360 117361 117362 ...... 117372 117373 117374 117375 117376 117377 117378 117379 117380 117381 117382 117383 117384 117385 117386 ...... 117399 117400 117401 117402 117403 117404 117405 117406 117407 117408 117409 117410 117411 117412 117413 ...... 117640 117641 117642 117643 117644 117645 117646 117647 117648 117649 117650 117651 117652 117653 117654 117655 117656 117657 117658 ...... 117792 117793 117794 117795 117796 117797 117798 117799 117800 117801 117802 117803 117804 117805 117806 117807 117808 117809 117810 ...... 117894 117895 117896 117897 117898 117899 117900 117901 117902 117903 117904 117905 117906 117907 117908 117909 117910 117911 117912 117913 117914 117915 117916 117917 ...... 117927 117928 117929 117930 117931 117932 117933 117934 117935 117936 117937 117938 117939 117940 117941 117942 117943 117944 117945 117946 117947 117948 117949 117950 117951 ...... 117960 117961 117962 117963 117964 117965 117966 117967 117968 117969 117970 117971 117972 117973 117974 117975 117976 117977 117978 117979 117980 117981 117982 117983 117984 117985 117986 117987 117988 117989 117990 117991 117992 117993 117994 117995 117996 117997 117998 117999 118000 118001 118002 118003 118004 ...... 118022 118023 118024 118025 118026 118027 118028 118029 118030 118031 118032 118033 118034 118035 118036 ...... 118265 118266 118267 118268 118269 118270 118271 118272 118273 118274 118275 118276 118277 118278 118279 118280 ...... 118340 118341 118342 118343 118344 118345 118346 118347 118348 118349 118350 118351 118352 118353 118354 118355 118356 118357 ...... 118593 118594 118595 118596 118597 118598 118599 118600 118601 118602 118603 118604 118605 118606 118607 118608 118609 118610 118611 118612 118613 118614 118615 118616 118617 118618 118619 118620 118621 118622 118623 ...... 118668 118669 118670 118671 118672 118673 118674 118675 118676 118677 118678 118679 118680 118681 118682 118683 118684 118685 118686 118687 118688 118689 118690 118691 118692 118693 118694 118695 118696 118697 118698 118699 118700 118701 118702 118703 118704 118705 118706 118707 118708 118709 118710 118711 118712 118713 118714 118715 118716 118717 118718 118719 118720 118721 ...... 118726 118727 118728 118729 118730 118731 118732 118733 118734 118735 118736 118737 118738 118739 118740 118741 118742 118743 118744 118745 118746 118747 118748 118749 118750 118751 118752 118753 118754 ...... 118767 118768 118769 118770 118771 118772 118773 118774 118775 118776 118777 118778 118779 118780 118781 118782 118783 118784 118785 118786 118787 118788 118789 118790 118791 118792 118793 118794 118795 118796 118797 118798 118799 118800 118801 118802 118803 118804 118805 118806 118807 118808 118809 ...... 118819 118820 118821 118822 118823 118824 118825 118826 118827 118828 118829 118830 118831 118832 118833 118834 118835 118836 118837 118838 118839 118840 118841 118842 118843 118844 118845 118846 118847 118848 118849 118850 118851 118852 118853 118854 118855 118856 118857 118858 118859 118860 118861 118862 118863 118864 118865 118866 118867 118868 118869 118870 118871 118872 118873 118874 118875 118876 118877 118878 118879 118880 ...... 118932 118933 118934 118935 118936 118937 118938 118939 118940 118941 118942 118943 118944 118945 ...... 118951 118952 118953 118954 118955 118956 118957 118958 118959 118960 118961 118962 118963 118964 118965 ...... 119026 119027 119028 119029 119030 119031 119032 119033 119034 119035 119036 119037 119038 119039 119040 119041 119042 119043 119044 119045 119046 119047 119048 119049 119050 119051 119052 119053 119054 119055 119056 119057 119058 119059 119060 119061 119062 119063 119064 119065 119066 119067 119068 119069 119070 ...... 119099 119100 119101 119102 119103 119104 119105 119106 119107 119108 119109 119110 119111 119112 119113 119114 119115 119116 119117 119118 119119 119120 119121 119122 119123 119124 119125 ...... 119384 119385 119386 119387 119388 119389 119390 119391 119392 119393 119394 119395 119396 119397 119398 ...... 119522 119523 119524 119525 119526 119527 119528 119529 119530 119531 119532 119533 119534 119535 119536 119537 119538 119539 119540 119541 119542 119543 119544 ...... 119698 119699 119700 119701 119702 119703 119704 119705 119706 119707 119708 119709 119710 119711 119712 119713 119714 119715 119716 119717 119718 119719 119720 119721 119722 ...... 119773 119774 119775 119776 119777 119778 119779 119780 119781 119782 119783 119784 119785 119786 119787 119788 119789 119790 119791 119792 119793 119794 119795 119796 119797 119798 119799 119800 ...... 120385 120386 120387 120388 120389 120390 120391 120392 120393 120394 120395 120396 120397 120398 120399 120400 120401 120402 120403 120404 120405 120406 ...... 120446 120447 120448 120449 120450 120451 120452 120453 120454 120455 120456 120457 120458 120459 120460 ...... 120559 120560 120561 120562 120563 120564 120565 120566 120567 120568 120569 120570 120571 120572 120573 120574 120575 120576 120577 120578 120579 120580 120581 120582 120583 120584 120585 120586 120587 120588 120589 120590 120591 120592 120593 120594 120595 120596 120597 120598 120599 120600 120601 120602 120603 120604 120605 120606 120607 120608 120609 120610 120611 120612 120613 120614 120615 120616 120617 120618 120619 120620 120621 120622 120623 120624 120625 120626 120627 120628 120629 120630 120631 120632 120633 ...... 120635 120636 120637 120638 120639 120640 120641 120642 120643 120644 120645 120646 120647 120648 120649 120650 120651 120652 120653 120654 120655 120656 120657 120658 120659 120660 120661 120662 120663 120664 120665 120666 120667 120668 120669 120670 120671 120672 120673 120674 120675 120676 120677 120678 120679 120680 120681 120682 120683 120684 120685 120686 120687 120688 120689 120690 120691 120692 120693 120694 120695 120696 120697 120698 120699 120700 120701 120702 120703 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 120814 120815 120816 120817 120818 120819 120820 120821 120822 120823 120824 120825 120826 120827 120828 120829 120830 120831 120832 120833 120834 120835 120836 ...... 121011 121012 121013 121014 121015 121016 121017 121018 121019 121020 121021 121022 121023 121024 121025 121026 121027 121028 121029 121030 121031 121032 ...... 121043 121044 121045 121046 121047 121048 121049 121050 121051 121052 121053 121054 121055 121056 121057 121058 121059 121060 121061 121062 121063 121064 121065 121066 121067 121068 ...... 121117 121118 121119 121120 121121 121122 121123 121124 121125 121126 121127 121128 121129 121130 121131 121132 121133 ...... 121144 121145 121146 121147 121148 121149 121150 121151 121152 121153 121154 121155 121156 121157 121158 121159 121160 121161 121162 121163 121164 121165 121166 121167 121168 121169 121170 121171 121172 121173 121174 121175 121176 121177 121178 121179 121180 121181 121182 121183 121184 121185 121186 121187 ...... 121501 121502 121503 121504 121505 121506 121507 121508 121509 121510 121511 121512 121513 121514 121515 ...... 121558 121559 121560 121561 121562 121563 121564 121565 121566 121567 121568 121569 121570 121571 121572 ...... 121613 121614 121615 121616 121617 121618 121619 121620 121621 121622 121623 121624 121625 121626 121627 ...... 121645 121646 121647 121648 121649 121650 121651 121652 121653 121654 121655 121656 121657 121658 121659 ...... 121855 121856 121857 121858 121859 121860 121861 121862 121863 121864 121865 121866 121867 121868 121869 121870 121871 121872 121873 121874 ...... 121914 121915 121916 121917 121918 121919 121920 121921 121922 121923 121924 121925 121926 121927 121928 ...... 122002 122003 122004 122005 122006 122007 122008 122009 122010 122011 122012 122013 122014 122015 122016 122017 122018 122019 122020 122021 122022 122023 122024 ...... 122305 122306 122307 122308 122309 122310 122311 122312 122313 122314 122315 122316 122317 122318 122319 122320 122321 122322 122323 122324 122325 122326 122327 122328 122329 122330 122331 122332 122333 122334 122335 122336 ...... 122447 122448 122449 122450 122451 122452 122453 122454 122455 122456 122457 122458 122459 122460 122461 122462 122463 122464 122465 122466 122467 122468 122469 122470 122471 122472 122473 122474 122475 122476 122477 122478 122479 122480 122481 122482 122483 122484 122485 122486 122487 122488 122489 122490 122491 122492 122493 122494 122495 122496 122497 122498 122499 122500 122501 ...... 122511 122512 122513 122514 122515 122516 122517 122518 122519 122520 122521 122522 122523 122524 122525 122526 122527 122528 122529 122530 122531 122532 122533 122534 122535 122536 122537 122538 122539 ...... 122576 122577 122578 122579 122580 122581 122582 122583 122584 122585 122586 122587 122588 122589 122590 122591 122592 122593 122594 122595 122596 122597 122598 122599 122600 122601 122602 122603 122604 122605 122606 122607 122608 122609 122610 122611 122612 122613 122614 ...... 122658 122659 122660 122661 122662 122663 122664 122665 122666 122667 122668 122669 122670 122671 ...... 122805 122806 122807 122808 122809 122810 122811 122812 122813 122814 122815 122816 122817 122818 122819 ...... 123108 123109 123110 123111 123112 123113 123114 123115 123116 123117 123118 123119 123120 123121 123122 ...... 123252 123253 123254 123255 123256 123257 123258 123259 123260 123261 123262 123263 123264 123265 123266 ...... 123287 123288 123289 123290 123291 123292 123293 123294 123295 123296 123297 123298 123299 123300 123301 123302 123303 123304 123305 123306 ...... 124092 124093 124094 124095 124096 124097 124098 124099 124100 124101 124102 124103 124104 124105 124106 ...... 125413 125414 125415 125416 125417 125418 125419 125420 125421 125422 125423 125424 125425 125426 125427 125428 125429 125430 125431 125432 125433 125434 125435 125436 125437 125438 125439 ...... 125610 125611 125612 125613 125614 125615 125616 125617 125618 125619 125620 125621 125622 125623 125624 ...... 125633 125634 125635 125636 125637 125638 125639 125640 125641 125642 125643 125644 125645 125646 125647 125648 125649 125650 125651 ...... 125748 125749 125750 125751 125752 125753 125754 125755 125756 125757 125758 125759 125760 125761 125762 125763 ...... 125817 125818 125819 125820 125821 125822 125823 125824 125825 125826 125827 125828 125829 125830 ...... 125893 125894 125895 125896 125897 125898 125899 125900 125901 125902 125903 125904 125905 125906 125907 125908 ...... 126369 126370 126371 126372 126373 126374 126375 126376 126377 126378 126379 126380 126381 126382 126383 126384 126385 126386 126387 126388 126389 ...... 126495 126496 126497 126498 126499 126500 126501 126502 126503 126504 126505 126506 126507 126508 ...... 126584 126585 126586 126587 126588 126589 126590 126591 126592 126593 126594 126595 126596 126597 126598 126599 126600 126601 ...... 126604 126605 126606 126607 126608 126609 126610 126611 126612 126613 126614 126615 126616 126617 126618 126619 126620 126621 126622 126623 126624 126625 126626 126627 126628 126629 126630 126631 126632 126633 126634 126635 126636 126637 126638 126639 126640 126641 126642 126643 126644 126645 126646 126647 126648 126649 126650 126651 126652 126653 126654 126655 126656 126657 126658 126659 126660 126661 126662 126663 126664 126665 126666 ...... 127630 127631 127632 127633 127634 127635 127636 127637 127638 127639 127640 127641 127642 127643 127644 127645 127646 127647 127648 127649 127650 127651 127652 ...... 128451 128452 128453 128454 128455 128456 128457 128458 128459 128460 128461 128462 128463 128464 128465 ...... 128674 128675 128676 128677 128678 128679 128680 128681 128682 128683 128684 128685 128686 128687 128688 ...... 128727 128728 128729 128730 128731 128732 128733 128734 128735 128736 128737 128738 128739 128740 128741 128742 128743 ...... 130006 130007 130008 130009 130010 130011 130012 130013 130014 130015 130016 130017 130018 130019 130020 130021 130022 130023 130024 130025 ...... 130033 130034 130035 130036 130037 130038 130039 130040 130041 130042 130043 130044 130045 130046 130047 130048 130049 130050 130051 130052 ...... 130058 130059 130060 130061 130062 130063 130064 130065 130066 130067 130068 130069 130070 130071 130072 130073 130074 130075 130076 130077 130078 130079 130080 130081 ...... 130098 130099 130100 130101 130102 130103 130104 130105 130106 130107 130108 130109 130110 130111 130112 130113 130114 130115 130116 130117 130118 130119 130120 130121 130122 130123 130124 130125 130126 130127 130128 130129 130130 130131 130132 130133 130134 130135 130136 130137 130138 130139 130140 130141 130142 130143 130144 130145 130146 130147 130148 130149 130150 130151 130152 130153 ...... 130390 130391 130392 130393 130394 130395 130396 130397 130398 130399 130400 130401 130402 130403 130404 ...... 130592 130593 130594 130595 130596 130597 130598 130599 130600 130601 130602 130603 130604 130605 130606 130607 130608 130609 130610 130611 130612 130613 130614 130615 130616 130617 130618 130619 130620 130621 130622 130623 ...... 130972 130973 130974 130975 130976 130977 130978 130979 130980 130981 130982 130983 130984 130985 130986 130987 130988 130989 130990 130991 130992 130993 130994 130995 130996 130997 130998 130999 131000 131001 131002 131003 131004 131005 131006 131007 131008 131009 131010 131011 131012 131013 131014 131015 131016 131017 131018 131019 131020 ...... 131685 131686 131687 131688 131689 131690 131691 131692 131693 131694 131695 131696 131697 131698 131699 131700 ...... 131890 131891 131892 131893 131894 131895 131896 131897 131898 131899 131900 131901 131902 131903 ...... 132141 132142 132143 132144 132145 132146 132147 132148 132149 132150 132151 132152 132153 132154 132155 ...... 132189 132190 132191 132192 132193 132194 132195 132196 132197 132198 132199 132200 132201 132202 132203 132204 132205 132206 132207 132208 132209 132210 132211 132212 132213 132214 132215 132216 132217 132218 132219 132220 132221 132222 132223 132224 132225 132226 132227 132228 132229 132230 132231 132232 132233 132234 132235 132236 132237 132238 ...... 133152 133153 133154 133155 133156 133157 133158 133159 133160 133161 133162 133163 133164 133165 133166 133167 133168 133169 133170 133171 133172 133173 133174 133175 133176 133177 ...... 133184 133185 133186 133187 133188 133189 133190 133191 133192 133193 133194 133195 133196 133197 ...... 133936 133937 133938 133939 133940 133941 133942 133943 133944 133945 133946 133947 133948 133949 133950 ...... 134846 134847 134848 134849 134850 134851 134852 134853 134854 134855 134856 134857 134858 134859 134860 134861 134862 134863 134864 134865 134866 134867 ...... 134925 134926 134927 134928 134929 134930 134931 134932 134933 134934 134935 134936 134937 134938 134939 ...... 134952 134953 134954 134955 134956 134957 134958 134959 134960 134961 134962 134963 134964 134965 134966 134967 134968 134969 134970 134971 134972 134973 134974 134975 134976 134977 134978 ...... 135601 135602 135603 135604 135605 135606 135607 135608 135609 135610 135611 135612 135613 135614 ...... 135810 135811 135812 135813 135814 135815 135816 135817 135818 135819 135820 135821 135822 135823 135824 135825 135826 135827 135828 135829 135830 135831 135832 135833 135834 135835 135836 135837 135838 135839 135840 135841 135842 135843 135844 135845 135846 135847 135848 135849 135850 135851 135852 135853 135854 ...... 136063 136064 136065 136066 136067 136068 136069 136070 136071 136072 136073 136074 136075 136076 136077 ...... 136644 136645 136646 136647 136648 136649 136650 136651 136652 136653 136654 136655 136656 136657 136658 136659 136660 136661 136662 136663 136664 136665 136666 136667 136668 136669 136670 ...... 136763 136764 136765 136766 136767 136768 136769 136770 136771 136772 136773 136774 136775 136776 136777 136778 136779 136780 136781 136782 136783 136784 136785 136786 136787 136788 136789 136790 136791 136792 136793 136794 136795 136796 136797 136798 136799 136800 136801 136802 136803 136804 136805 136806 136807 136808 136809 136810 136811 136812 136813 136814 136815 136816 136817 136818 136819 136820 136821 136822 136823 136824 136825 136826 136827 136828 136829 136830 136831 136832 136833 136834 136835 136836 136837 136838 136839 136840 136841 136842 136843 136844 136845 136846 136847 136848 136849 136850 136851 136852 136853 136854 136855 136856 136857 136858 136859 136860 136861 136862 136863 136864 136865 136866 136867 136868 136869 136870 136871 136872 136873 136874 136875 136876 136877 136878 136879 136880 136881 136882 136883 136884 136885 136886 136887 136888 136889 136890 136891 136892 136893 136894 136895 136896 136897 136898 136899 136900 136901 136902 136903 136904 136905 136906 136907 136908 136909 136910 136911 136912 136913 136914 136915 136916 136917 136918 136919 136920 136921 136922 136923 136924 136925 136926 136927 136928 136929 136930 136931 136932 136933 136934 136935 136936 136937 136938 136939 136940 136941 136942 136943 136944 136945 136946 136947 136948 136949 136950 136951 136952 136953 136954 136955 136956 136957 136958 136959 136960 136961 136962 136963 136964 136965 136966 136967 136968 136969 136970 136971 136972 136973 136974 136975 136976 136977 136978 136979 136980 136981 136982 136983 136984 136985 136986 136987 136988 136989 136990 136991 136992 136993 136994 136995 136996 136997 136998 136999 137000 137001 137002 137003 137004 137005 137006 137007 137008 137009 137010 137011 137012 137013 137014 137015 137016 137017 137018 137019 137020 137021 137022 137023 137024 137025 137026 137027 137028 137029 137030 137031 137032 137033 137034 137035 137036 137037 137038 137039 137040 137041 137042 137043 137044 137045 137046 137047 137048 137049 137050 137051 137052 137053 137054 137055 137056 137057 137058 137059 137060 137061 137062 137063 137064 137065 137066 137067 137068 137069 137070 137071 137072 137073 137074 137075 137076 137077 137078 137079 137080 137081 137082 137083 137084 137085 137086 137087 137088 137089 137090 137091 137092 137093 137094 137095 137096 137097 137098 137099 137100 137101 137102 137103 137104 137105 137106 137107 137108 137109 137110 137111 137112 137113 137114 137115 137116 137117 137118 137119 137120 137121 137122 137123 137124 137125 137126 137127 137128 137129 137130 137131 137132 137133 137134 137135 137136 137137 137138 137139 137140 137141 137142 137143 137144 137145 137146 137147 137148 137149 137150 137151 137152 137153 137154 137155 137156 137157 137158 137159 137160 137161 137162 137163 137164 137165 137166 137167 137168 137169 137170 137171 137172 137173 137174 137175 137176 137177 137178 137179 137180 137181 137182 137183 137184 137185 ...... 137241 137242 137243 137244 137245 137246 137247 137248 137249 137250 137251 137252 137253 137254 137255 137256 137257 137258 137259 137260 137261 137262 137263 137264 137265 137266 137267 137268 137269 137270 137271 137272 137273 137274 137275 137276 137277 137278 137279 137280 137281 137282 137283 137284 137285 137286 137287 137288 137289 137290 137291 137292 137293 137294 137295 137296 137297 137298 137299 137300 137301 137302 137303 137304 137305 137306 137307 137308 137309 137310 137311 137312 137313 137314 137315 137316 137317 137318 137319 137320 137321 ...... 137400 137401 137402 137403 137404 137405 137406 137407 137408 137409 137410 137411 137412 137413 137414 137415 137416 137417 137418 137419 137420 137421 137422 137423 137424 137425 137426 137427 137428 ...... 141467 141468 141469 141470 141471 141472 141473 141474 141475 141476 141477 141478 141479 141480 141481 141482 141483 141484 141485 ...... 141856 141857 141858 141859 141860 141861 141862 141863 141864 141865 141866 141867 141868 141869 141870 141871 141872 141873 141874 141875 141876 141877 ...... 142084 142085 142086 142087 142088 142089 142090 142091 142092 142093 142094 142095 142096 142097 142098 ...... 142112 142113 142114 142115 142116 142117 142118 142119 142120 142121 142122 142123 142124 142125 142126 142127 142128 142129 142130 142131 142132 142133 142134 142135 142136 142137 142138 142139 142140 142141 142142 142143 142144 142145 ...... 142213 142214 142215 142216 142217 142218 142219 142220 142221 142222 142223 142224 142225 142226 ...... 142242 142243 142244 142245 142246 142247 142248 142249 142250 142251 142252 142253 142254 142255 142256 ...... 142649 142650 142651 142652 142653 142654 142655 142656 142657 142658 142659 142660 142661 142662 142663 ...... 142677 142678 142679 142680 142681 142682 142683 142684 142685 142686 142687 142688 142689 142690 142691 142692 142693 142694 142695 142696 142697 142698 142699 142700 142701 142702 142703 142704 142705 ...... 143593 143594 143595 143596 143597 143598 143599 143600 143601 143602 143603 143604 143605 143606 143607 ...... 144470 144471 144472 144473 144474 144475 144476 144477 144478 144479 144480 144481 144482 144483 ...... 145130 145131 145132 145133 145134 145135 145136 145137 145138 145139 145140 145141 145142 145143 145144 ...... 145153 145154 145155 145156 145157 145158 145159 145160 145161 145162 145163 145164 145165 145166 145167 ...... 145220 145221 145222 145223 145224 145225 145226 145227 145228 145229 145230 145231 145232 145233 145234 145235 145236 145237 145238 145239 145240 145241 145242 145243 145244 145245 145246 145247 145248 145249 ...... 145377 145378 145379 145380 145381 145382 145383 145384 145385 145386 145387 145388 145389 145390 145391 ...... 150186 150187 150188 150189 150190 150191 150192 150193 150194 150195 150196 150197 150198 150199 150200 150201 ...... 150405 150406 150407 150408 150409 150410 150411 150412 150413 150414 150415 150416 150417 150418 150419 150420 150421 ...... 165420 165421 165422 165423 165424 165425 165426 165427 165428 165429 165430 165431 165432 165433 165434 165435 165436 165437 165438 165439 165440 165441 165442 165443 165444 165445 165446 165447 165448 165449 ...... 166730 166731 166732 166733 166734 166735 166736 166737 166738 166739 166740 166741 166742 166743 166744 166745 166746 166747 166748 166749 166750 166751 166752 166753 166754 166755 166756 166757 166758 166759 166760 166761 166762 166763 166764 166765 166766 166767 166768 166769 166770 ...... 167958 167959 167960 167961 167962 167963 167964 167965 167966 167967 167968 167969 167970 167971 167972 ...... 168519 168520 168521 168522 168523 168524 168525 168526 168527 168528 168529 168530 168531 168532 168533 ...... 168794 168795 168796 168797 168798 168799 168800 168801 168802 168803 168804 168805 168806 168807 168808 ...... 168811 168812 168813 168814 168815 168816 168817 168818 168819 168820 168821 168822 168823 168824 168825 ...... 168986 168987 168988 168989 168990 168991 168992 168993 168994 168995 168996 168997 168998 168999 169000 169001 169002 169003 169004 169005 169006 169007 169008 ...... 169036 169037 169038 169039 169040 169041 169042 169043 169044 169045 169046 169047 169048 169049 169050 169051 169052 169053 169054 169055 169056 169057 169058 169059 ...... 170141 170142 170143 170144 170145 170146 170147 170148 170149 170150 170151 170152 170153 170154 ...... 170267 170268 170269 170270 170271 170272 170273 170274 170275 170276 170277 170278 170279 170280 170281 ...... 170376 170377 170378 170379 170380 170381 170382 170383 170384 170385 170386 170387 170388 170389 ...... 170652 170653 170654 170655 170656 170657 170658 170659 170660 170661 170662 170663 170664 170665 170666 170667 170668 170669 170670 170671 170672 170673 170674 170675 170676 170677 170678 170679 170680 170681 170682 170683 170684 170685 170686 170687 170688 170689 170690 ...... 170739 170740 170741 170742 170743 170744 170745 170746 170747 170748 170749 170750 170751 170752 ...... 170773 170774 170775 170776 170777 170778 170779 170780 170781 170782 170783 170784 170785 170786 ...... 170803 170804 170805 170806 170807 170808 170809 170810 170811 170812 170813 170814 170815 170816 170817 ...... 170858 170859 170860 170861 170862 170863 170864 170865 170866 170867 170868 170869 170870 170871 170872 ...... 173690 173691 173692 173693 173694 173695 173696 173697 173698 173699 173700 173701 173702 173703 ...... 174062 174063 174064 174065 174066 174067 174068 174069 174070 174071 174072 174073 174074 174075 ...... 174249 174250 174251 174252 174253 174254 174255 174256 174257 174258 174259 174260 174261 174262 174263 174264 174265 174266 174267 174268 174269 174270 174271 174272 174273 ...... 174285 174286 174287 174288 174289 174290 174291 174292 174293 174294 174295 174296 174297 174298 ...... 174403 174404 174405 174406 174407 174408 174409 174410 174411 174412 174413 174414 174415 174416 174417 174418 174419 174420 174421 ...... 174426 174427 174428 174429 174430 174431 174432 174433 174434 174435 174436 174437 174438 174439 ...... 174815 174816 174817 174818 174819 174820 174821 174822 174823 174824 174825 174826 174827 174828 ...... 174891 174892 174893 174894 174895 174896 174897 174898 174899 174900 174901 174902 174903 174904 174905 ...... 175079 175080 175081 175082 175083 175084 175085 175086 175087 175088 175089 175090 175091 175092 ...... 175794 175795 175796 175797 175798 175799 175800 175801 175802 175803 175804 175805 175806 175807 ...... 184384 184385 184386 184387 184388 184389 184390 184391 184392 184393 184394 184395 184396 184397 184398 ...... 200104 200105 200106 200107 200108 200109 200110 200111 200112 200113 200114 200115 200116 200117 200118 200119 200120 200121 200122 200123 200124 200125 200126 200127 200128 200129 200130 200131 200132 200133 200134 200135 200136 200137 200138 200139 ...... 200177 200178 200179 200180 200181 200182 200183 200184 200185 200186 200187 200188 200189 200190 200191 ...... 203353 203354 203355 203356 203357 203358 203359 203360 203361 203362 203363 203364 203365 203366 ...... 203368 203369 203370 203371 203372 203373 203374 203375 203376 203377 203378 203379 203380 203381 203382 ...... 203388 203389 203390 203391 203392 203393 203394 203395 203396 203397 203398 203399 203400 203401 203402 203403 203404 203405 203406 203407 203408 203409 203410 203411 ...... 203424 203425 203426 203427 203428 203429 203430 203431 203432 203433 203434 203435 203436 203437 ...... 203485 203486 203487 203488 203489 203490 203491 203492 203493 203494 203495 203496 203497 203498 203499 ...... 203559 203560 203561 203562 203563 203564 203565 203566 203567 203568 203569 203570 203571 203572 ...... 203702 203703 203704 203705 203706 203707 203708 203709 203710 203711 203712 203713 203714 203715 203716 203717 203718 203719 203720 203721 203722 203723 203724 203725 203726 203727 203728 203729 203730 203731 203732 203733 203734 ...... 203744 203745 203746 203747 203748 203749 203750 203751 203752 203753 203754 203755 203756 203757 203758 203759 203760 203761 203762 203763 203764 203765 203766 203767 203768 203769 203770 203771 203772 203773 203774 203775 203776 203777 203778 203779 203780 203781 203782 203783 203784 203785 203786 203787 203788 203789 203790 203791 203792 203793 203794 203795 203796 203797 203798 203799 203800 203801 203802 203803 203804 203805 203806 203807 203808 203809 203810 203811 203812 203813 ...... 203829 203830 203831 203832 203833 203834 203835 203836 203837 203838 203839 203840 203841 203842 203843 ...... 203869 203870 203871 203872 203873 203874 203875 203876 203877 203878 203879 203880 203881 203882 203883 203884 203885 203886 203887 ...... 203915 203916 203917 203918 203919 203920 203921 203922 203923 203924 203925 203926 203927 203928 203929 203930 203931 203932 203933 203934 ...... 204012 204013 204014 204015 204016 204017 204018 204019 204020 204021 204022 204023 204024 204025 204026 204027 204028 204029 204030 204031 204032 204033 204034 204035 204036 204037 204038 204039 204040 204041 204042 ...... 204075 204076 204077 204078 204079 204080 204081 204082 204083 204084 204085 204086 204087 204088 204089 204090 204091 204092 204093 204094 204095 204096 204097 204098 204099 204100 204101 204102 204103 204104 ...... 204153 204154 204155 204156 204157 204158 204159 204160 204161 204162 204163 204164 204165 204166 204167 204168 204169 204170 ...... 204278 204279 204280 204281 204282 204283 204284 204285 204286 204287 204288 204289 204290 204291 204292 ...... 204303 204304 204305 204306 204307 204308 204309 |
/****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.20.0. 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 ................................................................................ "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), #endif #if SQLITE_ENABLE_API_ARMOR "ENABLE_API_ARMOR", #endif #if SQLITE_ENABLE_ATOMIC_WRITE "ENABLE_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_CEROD "ENABLE_CEROD", #endif #if SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif ................................................................................ ** Make sure the Tcl calling convention macro is defined. This macro is ** only used by test code and Tcl integration code. */ #ifndef SQLITE_TCLAPI # define SQLITE_TCLAPI #endif /* ** Make sure that rand_s() is available on Windows systems with MSVC 2005 ** or higher. */ #if defined(_MSC_VER) && _MSC_VER>=1400 # define _CRT_RAND_S #endif /* ** Include the header file used to customize the compiler options for MSVC. ** This should be done first so that it can successfully prevent spurious ** compiler warnings due to subsequent content in this file and other files ** that are included by this file. */ /************** Include msvc.h in the middle of sqliteInt.h ******************/ ................................................................................ ** Since [version 3.6.18] ([dateof:3.6.18]), ** SQLite source code has been stored in the ** <a href="http://www.fossil-scm.org/">Fossil configuration management ** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID ** string contains the date and time of the check-in (UTC) and a SHA1 ** or SHA3-256 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.20.0" #define SQLITE_VERSION_NUMBER 3020000 #define SQLITE_SOURCE_ID "2017-07-12 18:05:54 604c11d1a39f09e47b6fcee0f8b1c1054f9dbbc7b2c1cf93312aeaa4b7095018" /* ** 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 ................................................................................ ** programmers might include assert() statements in their application to ** verify that values returned by these interfaces match the macros in ** the header, and thus ensure that the application is ** compiled with matching library and header files. ** ** <blockquote><pre> ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER ); ** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 ); ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 ); ** </pre></blockquote>)^ ** ** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] ** macro. ^The sqlite3_libversion() function returns a pointer to the ** to the sqlite3_version[] string constant. The sqlite3_libversion() ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlite3_libversion_number() function returns an integer equal to ** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; SQLITE_API const char *sqlite3_libversion(void); SQLITE_API const char *sqlite3_sourceid(void); SQLITE_API int sqlite3_libversion_number(void); ................................................................................ ** ** 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_v3()], [sqlite3_create_function()], and ** [sqlite3_busy_timeout()] to name but three) that are methods on an ** sqlite3 object. */ typedef struct sqlite3 sqlite3; /* ** CAPI3REF: 64-Bit Integer Types ................................................................................ typedef int (*sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface ** METHOD: sqlite3 ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v3()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, ** semicolon-separate SQL statements passed into its 2nd argument, ** in the context of the [database connection] passed in as its 1st ** argument. ^If the callback function of the 3rd argument to ................................................................................ #define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ #define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* The database disk image is malformed */ #define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ #define SQLITE_EMPTY 16 /* Not used */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ ................................................................................ #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) ................................................................................ ** file that were written at the application level might have changed ** and that adjacent bytes, even bytes within the same sector are ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN ** flag indicates that a file cannot be deleted when open. The ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on ** read-only media and cannot be changed even by processes with ** elevated privileges. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 #define SQLITE_IOCAP_ATOMIC1K 0x00000004 #define SQLITE_IOCAP_ATOMIC2K 0x00000008 #define SQLITE_IOCAP_ATOMIC4K 0x00000010 #define SQLITE_IOCAP_ATOMIC8K 0x00000020 ................................................................................ #define SQLITE_IOCAP_ATOMIC32K 0x00000080 #define SQLITE_IOCAP_ATOMIC64K 0x00000100 #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods ** of an [sqlite3_io_methods] object. ................................................................................ ** <li> [SQLITE_IOCAP_ATOMIC32K] ** <li> [SQLITE_IOCAP_ATOMIC64K] ** <li> [SQLITE_IOCAP_SAFE_APPEND] ** <li> [SQLITE_IOCAP_SEQUENTIAL] ** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN] ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] ** <li> [SQLITE_IOCAP_IMMUTABLE] ** </ul> ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of ** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values ** mean that writes of blocks that are nnn bytes in size and ** are aligned to an address which is an integer multiple of ** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means ................................................................................ ** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other ** VFS should return SQLITE_NOTFOUND for this opcode. ** ** <li>[[SQLITE_FCNTL_RBU]] ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by ** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for ** this opcode. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 #define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 ................................................................................ #define SQLITE_FCNTL_WAL_BLOCK 24 #define SQLITE_FCNTL_ZIPVFS 25 #define SQLITE_FCNTL_RBU 26 #define SQLITE_FCNTL_VFS_POINTER 27 #define SQLITE_FCNTL_JOURNAL_POINTER 28 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 #define SQLITE_FCNTL_PDB 30 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO ................................................................................ ** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which ** is a pointer to an instance of the [sqlite3_mem_methods] structure. ** The [sqlite3_mem_methods] ** structure is filled with the currently defined memory allocation routines.)^ ** This option can be used to overload the default memory allocation ** routines with a wrapper that simulations memory allocation failure or ** tracks memory usage, for example. </dd> ** ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, ** interpreted as a boolean, which enables or disables the collection of ** memory allocation statistics. ^(When memory allocation statistics are ** disabled, the following SQLite interfaces become non-operational: ** <ul> ................................................................................ ** </ul>)^ ** ^Memory allocation statistics are enabled by default unless SQLite is ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory ** allocation statistics are disabled by default. ** </dd> ** ** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt> ** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer ** that SQLite can use for scratch memory. ^(There are three arguments ** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte ** aligned memory buffer from which the scratch allocations will be ** drawn, the size of each scratch allocation (sz), ** and the maximum number of scratch allocations (N).)^ ** The first argument must be a pointer to an 8-byte aligned buffer ** of at least sz*N bytes of memory. ** ^SQLite will not use more than one scratch buffers per thread. ** ^SQLite will never request a scratch buffer that is more than 6 ** times the database page size. ** ^If SQLite needs needs additional ** scratch memory beyond what is provided by this configuration option, then ** [sqlite3_malloc()] will be used to obtain the memory needed.<p> ** ^When the application provides any amount of scratch memory using ** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large ** [sqlite3_malloc|heap allocations]. ** This can help [Robson proof|prevent memory allocation failures] due to heap ** fragmentation in low-memory embedded systems. ** </dd> ** ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> ** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool ** that SQLite can use for the database page cache with the default page ** cache implementation. ** This configuration option is a no-op if an application-define page ................................................................................ ** page cache memory is needed beyond what is provided by the initial ** allocation, then SQLite goes to [sqlite3_malloc()] separately for each ** additional cache line. </dd> ** ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer ** that SQLite will use for all of its dynamic memory allocation needs ** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and ** [SQLITE_CONFIG_PAGECACHE]. ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns ** [SQLITE_ERROR] if invoked otherwise. ** ^There are three arguments to SQLITE_CONFIG_HEAP: ** An 8-byte aligned pointer to the memory, ** the number of bytes in the memory buffer, and the minimum allocation size. ** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts ................................................................................ ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ #define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ ................................................................................ #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second argument to the [sqlite3_db_config()] interface. ** ................................................................................ ** is an integer - non-zero to disable checkpoints-on-close, or zero (the ** default) to enable them. The second parameter is a pointer to an integer ** into which is written 0 or 1 to indicate whether checkpoints-on-close ** have been disabled - 0 if they are not disabled, 1 if they are. ** </dd> ** ** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates ** the [query planner stability guarantee] (QPSG). When the QPSG is active, ** a single SQL query statement will always use the same algorithm regardless ** of values of [bound parameters]. The QPSG disables some query optimizations ** that look at the values of bound parameters, which can make some queries ** slower. But the QPSG has the advantage of more predictable behavior. With ** the QPSG active, SQLite will always use the same query plan in the field as ** was used during testing in the lab. ** </dd> ** ** </dl> ................................................................................ ** to perform various actions, the authorizer callback is invoked to ** see if those actions are allowed. ^The authorizer callback should ** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the ** specific action but allow the SQL statement to continue to be ** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be ** rejected with an error. ^If the authorizer callback returns ** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] ** then the [sqlite3_prepare_v3()] or equivalent call that triggered ** the authorizer will fail with an error message. ** ** When the callback returns [SQLITE_OK], that means the operation ** requested is ok. ^When the callback returns [SQLITE_DENY], the ** [sqlite3_prepare_v3()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that ** access is denied. ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter ** to the callback is an integer [SQLITE_COPY | action code] that specifies ** the particular action to be authorized. ^The third through sixth parameters ................................................................................ ** ^(Only a single authorizer can be in place on a database connection ** at a time. Each call to sqlite3_set_authorizer overrides the ** previous call.)^ ^Disable the authorizer by installing a NULL callback. ** The authorizer is disabled by default. ** ** The authorizer callback must not do anything that will modify ** the database connection that invoked the authorizer callback. ** Note that [sqlite3_prepare_v3()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** ** ^When [sqlite3_prepare_v3()] is used to prepare a statement, the ** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlite3_step()]. ** ** ^Note that the authorizer callback is invoked only during ** [sqlite3_prepare()] or its variants. Authorization is not ** performed during statement evaluation in [sqlite3_step()], unless ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v3() to reprepare a statement after a schema change. */ SQLITE_API int sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData ); ................................................................................ ** ** ^If the progress callback returns non-zero, the operation is ** interrupted. This feature can be used to implement a ** "Cancel" button on a GUI progress dialog box. ** ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v3()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** */ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection ................................................................................ ** automatically deleted as soon as the database connection is closed. ** ** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> ** ** ^If [URI filename] interpretation is enabled, and the filename argument ** begins with "file:", then the filename is interpreted as a URI. ^URI ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is ** set in the fourth argument to sqlite3_open_v2(), or if it has ** been enabled globally using the [SQLITE_CONFIG_URI] option with the ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. ** As of SQLite version 3.7.7, URI filename interpretation is turned off ** by default, but future releases of SQLite might enable URI filename ** interpretation by default. See "[URI filenames]" for additional ** information. ** ** URI filenames are parsed according to RFC 3986. ^If the URI contains an ** authority, then it must be either an empty string or the string ** "localhost". ^If the authority is not an empty string or "localhost", an ................................................................................ ** original SQL text is source code. A prepared statement object ** is the compiled object code. All SQL must be converted into a ** prepared statement before it can be run. ** ** The life-cycle of a prepared statement object usually goes like this: ** ** <ol> ** <li> Create the prepared statement object using [sqlite3_prepare_v3()]. ** <li> Bind values to [parameters] using the sqlite3_bind_*() ** interfaces. ** <li> Run the SQL by calling [sqlite3_step()] one or more times. ** <li> Reset the prepared statement using [sqlite3_reset()] then go back ** to step 2. Do this zero or more times. ** <li> Destroy the object using [sqlite3_finalize()]. ** </ol> ................................................................................ ** <dd>The maximum depth of the parse tree on any expression.</dd>)^ ** ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^ ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> ** <dd>The maximum number of instructions in a virtual machine program ** used to implement an SQL statement. If [sqlite3_prepare_v3()] or ** the equivalent tries to allocate space for more than this many opcodes ** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^ ** ** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt> ** <dd>The maximum number of arguments on a function.</dd>)^ ** ** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt> ................................................................................ ** "prepFlags" parameter of the [sqlite3_prepare_v3()] and ** [sqlite3_prepare16_v3()] interfaces. ** ** New flags may be added in future releases of SQLite. ** ** <dl> ** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt> ** <dd>The SQLITE_PREPARE_PERSISTENT flag causes [sqlite3_prepare_v3()] ** and [sqlite3_prepare16_v3()] ** to optimize the resulting prepared statement to be retained for a ** relatively long amount of time.)^ ^Without this flag, ** [sqlite3_prepare_v3()] and [sqlite3_prepare16_v3()] assume that ** the prepared statement will be used just once or at most a few times ** and then destroyed using [sqlite3_finalize()] relatively soon. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 /* ** CAPI3REF: Compiling An SQL Statement ** KEYWORDS: {SQL statement compiler} ................................................................................ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLITE_API int sqlite3_prepare16_v3( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ unsigned int prepFalgs, /* Zero or more SQLITE_PREPARE_ flags */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); /* ** CAPI3REF: Retrieving Statement SQL ** METHOD: sqlite3_stmt ................................................................................ ** still make the distinction between protected and unprotected ** sqlite3_value objects even when not strictly required. ** ** ^The sqlite3_value objects that are passed as parameters into the ** implementation of [application-defined SQL functions] are protected. ** ^The sqlite3_value object returned by ** [sqlite3_column_value()] is unprotected. ** Unprotected sqlite3_value objects may only be used with ** [sqlite3_result_value()] and [sqlite3_bind_value()]. ** The [sqlite3_value_blob | sqlite3_value_type()] family of ** interfaces require protected sqlite3_value objects. */ typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object ................................................................................ /* ** CAPI3REF: Binding Values To Prepared Statements ** KEYWORDS: {host parameter} {host parameters} {host parameter name} ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} ** METHOD: sqlite3_stmt ** ** ^(In the SQL statement text input to [sqlite3_prepare_v3()] and its variants, ** literals may be replaced by a [parameter] that matches one of following ** templates: ** ** <ul> ** <li> ? ** <li> ?NNN ** <li> :VVV ................................................................................ ** In the templates above, NNN represents an integer literal, ** and VVV represents an alphanumeric identifier.)^ ^The values of these ** parameters (also called "host parameter names" or "SQL parameters") ** can be set using the sqlite3_bind_*() routines defined here. ** ** ^The first argument to the sqlite3_bind_*() routines is always ** a pointer to the [sqlite3_stmt] object returned from ** [sqlite3_prepare_v3()] or its variants. ** ** ^The second argument is the index of the SQL parameter to be set. ** ^The leftmost SQL parameter has an index of 1. ^When the same named ** SQL parameter is used more than once, second and subsequent ** occurrences have the same index as the first occurrence. ** ^The index for named parameters can be looked up using the ** [sqlite3_bind_parameter_index()] API if desired. ^The index ................................................................................ ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that ** is filled with zeroes. ^A zeroblob uses a fixed amount of memory ** (just an integer to hold its size) while it is being processed. ** Zeroblobs are intended to serve as placeholders for BLOBs whose ** content is later written using ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() ** routine is passed a [prepared statement] that has been finalized, the ** result is undefined and probably harmful. ................................................................................ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); /* ** CAPI3REF: Number Of SQL Parameters ** METHOD: sqlite3_stmt ** ................................................................................ ** </table></blockquote> ** ** <b>Details:</b> ** ** ^These routines return information about a single column of the current ** result row of a query. ^In every case the first argument is a pointer ** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] ** that was returned from [sqlite3_prepare_v3()] or one of its variants) ** and the second argument is the index of the column for which information ** should be returned. ^The leftmost column of the result set has the index 0. ** ^The number of columns in the result can be determined using ** [sqlite3_column_count()]. ** ** If the SQL statement does not currently point to a valid row, or if the ** column index is out of range, the result is undefined. ................................................................................ ** ** <b>Summary:</b> ** <blockquote><table border=0 cellpadding=0 cellspacing=0> ** <tr><td><b>sqlite3_value_blob</b><td>→<td>BLOB value ** <tr><td><b>sqlite3_value_double</b><td>→<td>REAL value ** <tr><td><b>sqlite3_value_int</b><td>→<td>32-bit INTEGER value ** <tr><td><b>sqlite3_value_int64</b><td>→<td>64-bit INTEGER value ** <tr><td><b>sqlite3_value_text</b><td>→<td>UTF-8 TEXT value ** <tr><td><b>sqlite3_value_text16</b><td>→<td>UTF-16 TEXT value in ** the native byteorder ** <tr><td><b>sqlite3_value_text16be</b><td>→<td>UTF-16be TEXT value ** <tr><td><b>sqlite3_value_text16le</b><td>→<td>UTF-16le TEXT value ** <tr><td> <td> <td> ** <tr><td><b>sqlite3_value_bytes</b><td>→<td>Size of a BLOB ................................................................................ ** datatype of the value ** <tr><td><b>sqlite3_value_numeric_type </b> ** <td>→ <td>Best numeric datatype of the value ** </table></blockquote> ** ** <b>Details:</b> ** ** This routine extract type, size, and content information from ** [protected sqlite3_value] objects. Protected sqlite3_value objects ** are used to pass parameter information into implementation of ** [application-defined SQL functions] and [virtual tables]. ** ** These routines work only with [protected sqlite3_value] objects. ** Any attempt to use these routines on an [unprotected sqlite3_value] ** is not threadsafe. ................................................................................ ** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. ** ** ^The sqlite3_value_text16() interface extracts a UTF-16 string ** in the native byte-order of the host machine. ^The ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** ** ^(The sqlite3_value_type(V) interface returns the ** [SQLITE_INTEGER | datatype code] for the initial datatype of the ** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER], ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ ** Other interfaces might change the datatype for an sqlite3_value object. ** For example, if the datatype is initially SQLITE_INTEGER and ** sqlite3_value_text(V) is called to extract a text value for that ................................................................................ ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); SQLITE_API double sqlite3_value_double(sqlite3_value*); SQLITE_API int sqlite3_value_int(sqlite3_value*); SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); SQLITE_API int sqlite3_value_bytes(sqlite3_value*); SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); SQLITE_API int sqlite3_value_type(sqlite3_value*); ................................................................................ ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** ** SQLite makes no use of subtype itself. It merely passes the subtype ** from the result of one [application-defined SQL function] into the ** input of another. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** ................................................................................ ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to ** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite ** assumes that the text or BLOB result is in constant space and does not ** copy the content of the parameter nor call a destructor on the content ** when it has finished using that result. ** ^If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT ** then SQLite makes a copy of the result into space obtained from ** from [sqlite3_malloc()] before it returns. ** ** ^The sqlite3_result_value() interface sets the result of ** the application-defined function to be a copy of the ** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The ** sqlite3_result_value() interface makes a copy of the [sqlite3_value] ** so that the [sqlite3_value] specified in the parameter may change or ** be deallocated after sqlite3_result_value() returns without harm. ** ^A [protected sqlite3_value] object may always be used where an ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, sqlite3_uint64,void(*)(void*)); ................................................................................ SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, void(*)(void*), unsigned char encoding); SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); /* ** CAPI3REF: Setting The Subtype Of An SQL Function ** METHOD: sqlite3_context ................................................................................ ** CAPI3REF: Find The Database Handle Of A Prepared Statement ** METHOD: sqlite3_stmt ** ** ^The sqlite3_db_handle interface returns the [database connection] handle ** to which a [prepared statement] belongs. ^The [database connection] ** returned by sqlite3_db_handle is the same [database connection] ** that was the first argument ** to the [sqlite3_prepare_v3()] call (or its variants) that was used to ** create the statement in the first place. */ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Filename For A Database Connection ** METHOD: sqlite3 ................................................................................ ** The commit and rollback hook callbacks are not reentrant. ** The callback implementation must not do anything that will modify ** the database connection that invoked the callback. Any actions ** to modify the database connection must be deferred until after the ** completion of the [sqlite3_step()] call that triggered the commit ** or rollback hook in the first place. ** Note that running any other SQL statements, including SELECT statements, ** or merely calling [sqlite3_prepare_v3()] and [sqlite3_step()] will modify ** the database connections for the meaning of "modify" in this paragraph. ** ** ^Registering a NULL function disables the callback. ** ** ^When the commit hook callback routine returns zero, the [COMMIT] ** operation is allowed to continue normally. ^If the commit hook ** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. ................................................................................ ** The exceptions defined in this paragraph might change in a future ** release of SQLite. ** ** The update hook implementation must not do anything that will modify ** the database connection that invoked the update hook. Any actions ** to modify the database connection must be deferred until after the ** completion of the [sqlite3_step()] call that triggered the update hook. ** Note that [sqlite3_prepare_v3()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** ** ^The sqlite3_update_hook(D,C,P) function ** returns the P argument from the previous call ** on the same [database connection] D, or NULL for ** the first call on D. ** ................................................................................ ** CAPI3REF: Virtual Table Constraint Operator Codes ** ** These macros defined the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents ** an operator that is part of a constraint term in the wHERE clause of ** a query that uses a [virtual table]. */ #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 #define SQLITE_INDEX_CONSTRAINT_GE 32 #define SQLITE_INDEX_CONSTRAINT_MATCH 64 #define SQLITE_INDEX_CONSTRAINT_LIKE 65 #define SQLITE_INDEX_CONSTRAINT_GLOB 66 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67 /* ** CAPI3REF: Register A Virtual Table Implementation ** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before ................................................................................ #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 #define SQLITE_TESTCTRL_PENDING_BYTE 11 #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 ................................................................................ ** that can be returned by [sqlite3_status()]. ** ** <dl> ** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt> ** <dd>This parameter is the current amount of memory checked out ** using [sqlite3_malloc()], either directly or indirectly. The ** figure includes calls made to [sqlite3_malloc()] by the application ** and internal memory usage by the SQLite library. Scratch memory ** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in ** this parameter. The amount returned is the sum of the allocation ** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^ ** ** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their ................................................................................ ** ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [pagecache memory allocator]. Only the value returned in the ** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** ** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt> ** <dd>This parameter returns the number of allocations used out of the ** [scratch memory allocator] configured using ** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not ** in bytes. Since a single thread may only have one scratch allocation ** outstanding at time, this parameter also reports the number of threads ** using scratch memory at the same time.</dd>)^ ** ** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of scratch memory ** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] ** buffer and where forced to overflow to [sqlite3_malloc()]. The values ** returned include overflows because the requested allocation was too ** larger (that is, because the requested allocation was larger than the ** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer ** slots were available. ** </dd>)^ ** ** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [scratch memory allocator]. Only the value returned in the ** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> ** <dd>The *pHighwater parameter records the deepest parser stack. ** The *pCurrent value is undefined. The *pHighwater value is only ** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^ ** </dl> ** ** New status parameters may be added from time to time. */ #define SQLITE_STATUS_MEMORY_USED 0 #define SQLITE_STATUS_PAGECACHE_USED 1 #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 #define SQLITE_STATUS_SCRATCH_USED 3 #define SQLITE_STATUS_SCRATCH_OVERFLOW 4 #define SQLITE_STATUS_MALLOC_SIZE 5 #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 #define SQLITE_STATUS_SCRATCH_SIZE 8 #define SQLITE_STATUS_MALLOC_COUNT 9 /* ** CAPI3REF: Database Connection Status ** METHOD: sqlite3 ** ** ^This interface is used to retrieve runtime status information ................................................................................ ** Changes within a patchset are ordered in the same way as for changesets ** generated by the sqlite3session_changeset() function (i.e. all changes for ** a single table are grouped together, tables appear in the order in which ** they were attached to the session object). */ SQLITE_API int sqlite3session_patchset( sqlite3_session *pSession, /* Session object */ int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ void **ppPatchset /* OUT: Buffer containing changeset */ ); /* ** CAPI3REF: Test if a changeset has recorded any changes. ** ** Return non-zero if no changes to attached tables have been recorded by ** the session object passed as the first argument. Otherwise, if one or ................................................................................ ** CAPI3REF: Streaming Versions of API functions. ** ** The six streaming API xxx_strm() functions serve similar purposes to the ** corresponding non-streaming API functions: ** ** <table border=1 style="margin-left:8ex;margin-right:8ex"> ** <tr><th>Streaming function<th>Non-streaming equivalent</th> ** <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] ** <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] ** <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] ** <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] ** <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] ** <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] ** </table> ** ** Non-streaming functions that accept changesets (or patchsets) as input ** require that the entire changeset be stored in a single buffer in memory. ** Similarly, those that return a changeset or patchset do so by returning ** a pointer to a single large buffer allocated using sqlite3_malloc(). ** Normally this is convenient. However, if an application running in a ................................................................................ # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif /* ** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is ** defined. We need to defend against those failures when testing with ** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches ** during a normal build. The following macro can be used to disable tests ** that are always false except when SQLITE_TEST_REALLOC_STRESS is set. */ ................................................................................ #define TK_EXISTS 20 #define TK_TEMP 21 #define TK_LP 22 #define TK_RP 23 #define TK_AS 24 #define TK_WITHOUT 25 #define TK_COMMA 26 #define TK_ID 27 #define TK_ABORT 28 #define TK_ACTION 29 #define TK_AFTER 30 #define TK_ANALYZE 31 #define TK_ASC 32 #define TK_ATTACH 33 #define TK_BEFORE 34 #define TK_BY 35 #define TK_CASCADE 36 #define TK_CAST 37 #define TK_COLUMNKW 38 #define TK_CONFLICT 39 #define TK_DATABASE 40 #define TK_DESC 41 #define TK_DETACH 42 #define TK_EACH 43 #define TK_FAIL 44 #define TK_FOR 45 #define TK_IGNORE 46 #define TK_INITIALLY 47 #define TK_INSTEAD 48 #define TK_LIKE_KW 49 #define TK_MATCH 50 #define TK_NO 51 #define TK_KEY 52 #define TK_OF 53 #define TK_OFFSET 54 #define TK_PRAGMA 55 #define TK_RAISE 56 #define TK_RECURSIVE 57 #define TK_REPLACE 58 #define TK_RESTRICT 59 #define TK_ROW 60 #define TK_TRIGGER 61 #define TK_VACUUM 62 #define TK_VIEW 63 #define TK_VIRTUAL 64 #define TK_WITH 65 #define TK_REINDEX 66 #define TK_RENAME 67 #define TK_CTIME_KW 68 #define TK_ANY 69 #define TK_OR 70 #define TK_AND 71 #define TK_IS 72 #define TK_BETWEEN 73 #define TK_IN 74 #define TK_ISNULL 75 #define TK_NOTNULL 76 #define TK_NE 77 #define TK_EQ 78 #define TK_GT 79 #define TK_LE 80 #define TK_LT 81 #define TK_GE 82 #define TK_ESCAPE 83 #define TK_BITAND 84 #define TK_BITOR 85 #define TK_LSHIFT 86 #define TK_RSHIFT 87 #define TK_PLUS 88 #define TK_MINUS 89 #define TK_STAR 90 ................................................................................ #define TK_CASE 136 #define TK_WHEN 137 #define TK_THEN 138 #define TK_ELSE 139 #define TK_INDEX 140 #define TK_ALTER 141 #define TK_ADD 142 #define TK_TO_TEXT 143 #define TK_TO_BLOB 144 #define TK_TO_NUMERIC 145 #define TK_TO_INT 146 #define TK_TO_REAL 147 #define TK_ISNOT 148 #define TK_END_OF_FILE 149 #define TK_UNCLOSED_STRING 150 #define TK_FUNCTION 151 #define TK_COLUMN 152 #define TK_AGG_FUNCTION 153 #define TK_AGG_COLUMN 154 #define TK_UMINUS 155 #define TK_UPLUS 156 #define TK_REGISTER 157 #define TK_VECTOR 158 #define TK_SELECT_COLUMN 159 #define TK_IF_NULL_ROW 160 #define TK_ASTERISK 161 #define TK_SPAN 162 #define TK_SPACE 163 #define TK_ILLEGAL 164 /* The token codes above must all fit in 8 bits */ #define TKFLG_MASK 0xff /* Flags that can be added to a token code when it is not ** being stored in a u8: */ #define TKFLG_DONTFOLD 0x100 /* Omit constant folding optimizations */ ................................................................................ ** The default value of "20" was choosen to minimize the run-time of the ** speedtest1 test program with options: --shrink-memory --reprepare */ #ifndef SQLITE_DEFAULT_PCACHE_INITSZ # define SQLITE_DEFAULT_PCACHE_INITSZ 20 #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) #endif ................................................................................ # undef SQLITE_ENABLE_STAT3_OR_STAT4 #endif /* ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not ** the Select query generator tracing logic is turned on. */ #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE) # define SELECTTRACE_ENABLED 1 #else # define SELECTTRACE_ENABLED 0 #endif /* ** An instance of the following structure is used to store the busy-handler ................................................................................ SQLITE_PRIVATE int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ int wrFlag, /* 1 for writing. 0 for read-only */ struct KeyInfo*, /* First argument to compare function */ BtCursor *pCursor /* Space to write cursor structure */ ); SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...); #endif ................................................................................ signed char p3; /* Third parameter */ }; typedef struct VdbeOpList VdbeOpList; /* ** Allowed values of VdbeOp.p4type */ #define P4_NOTUSED 0 /* The P4 parameter is not used */ #define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P4_STATIC (-2) /* Pointer to a static string */ #define P4_COLLSEQ (-3) /* P4 is a pointer to a CollSeq structure */ #define P4_FUNCDEF (-4) /* P4 is a pointer to a FuncDef structure */ #define P4_KEYINFO (-5) /* P4 is a pointer to a KeyInfo structure */ #define P4_EXPR (-6) /* P4 is a pointer to an Expr tree */ #define P4_MEM (-7) /* P4 is a pointer to a Mem* structure */ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_VTAB (-8) /* P4 is a pointer to an sqlite3_vtab structure */ #define P4_REAL (-9) /* P4 is a 64-bit floating point value */ #define P4_INT64 (-10) /* P4 is a 64-bit signed integer */ #define P4_INT32 (-11) /* P4 is a 32-bit signed integer */ #define P4_INTARRAY (-12) /* P4 is a vector of 32-bit integers */ #define P4_SUBPROGRAM (-13) /* P4 is a pointer to a SubProgram structure */ #define P4_ADVANCE (-14) /* P4 is a pointer to BtreeNext() or BtreePrev() */ #define P4_TABLE (-15) /* P4 is a pointer to a Table structure */ #define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 #define P5_ConstraintUnique 2 #define P5_ConstraintCheck 3 #define P5_ConstraintFK 4 ................................................................................ /************** Include opcodes.h in the middle of vdbe.h ********************/ /************** Begin file opcodes.h *****************************************/ /* Automatically generated. Do not edit */ /* See the tool/mkopcodeh.tcl script for details */ #define OP_Savepoint 0 #define OP_AutoCommit 1 #define OP_Transaction 2 #define OP_SorterNext 3 #define OP_PrevIfOpen 4 #define OP_NextIfOpen 5 #define OP_Prev 6 #define OP_Next 7 #define OP_Checkpoint 8 #define OP_JournalMode 9 #define OP_Vacuum 10 #define OP_VFilter 11 /* synopsis: iplan=r[P3] zplan='P4' */ #define OP_VUpdate 12 /* synopsis: data=r[P3@P2] */ #define OP_Goto 13 #define OP_Gosub 14 #define OP_InitCoroutine 15 #define OP_Yield 16 #define OP_MustBeInt 17 #define OP_Jump 18 #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ #define OP_Once 20 #define OP_If 21 #define OP_IfNot 22 #define OP_IfNullRow 23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ #define OP_SeekLT 24 /* synopsis: key=r[P3@P4] */ #define OP_SeekLE 25 /* synopsis: key=r[P3@P4] */ #define OP_SeekGE 26 /* synopsis: key=r[P3@P4] */ #define OP_SeekGT 27 /* synopsis: key=r[P3@P4] */ #define OP_NoConflict 28 /* synopsis: key=r[P3@P4] */ #define OP_NotFound 29 /* synopsis: key=r[P3@P4] */ #define OP_Found 30 /* synopsis: key=r[P3@P4] */ #define OP_SeekRowid 31 /* synopsis: intkey=r[P3] */ #define OP_NotExists 32 /* synopsis: intkey=r[P3] */ #define OP_Last 33 #define OP_IfSmaller 34 #define OP_SorterSort 35 #define OP_Sort 36 #define OP_Rewind 37 #define OP_IdxLE 38 /* synopsis: key=r[P3@P4] */ #define OP_IdxGT 39 /* synopsis: key=r[P3@P4] */ #define OP_IdxLT 40 /* synopsis: key=r[P3@P4] */ #define OP_IdxGE 41 /* synopsis: key=r[P3@P4] */ #define OP_RowSetRead 42 /* synopsis: r[P3]=rowset(P1) */ #define OP_RowSetTest 43 /* synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Program 44 #define OP_FkIfZero 45 /* synopsis: if fkctr[P1]==0 goto P2 */ #define OP_IfPos 46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ #define OP_IfNotZero 47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ #define OP_DecrJumpZero 48 /* synopsis: if (--r[P1])==0 goto P2 */ #define OP_IncrVacuum 49 #define OP_VNext 50 #define OP_Init 51 /* synopsis: Start at P2 */ #define OP_Return 52 #define OP_EndCoroutine 53 #define OP_HaltIfNull 54 /* synopsis: if r[P3]=null halt */ #define OP_Halt 55 #define OP_Integer 56 /* synopsis: r[P2]=P1 */ #define OP_Int64 57 /* synopsis: r[P2]=P4 */ #define OP_String 58 /* synopsis: r[P2]='P4' (len=P1) */ #define OP_Null 59 /* synopsis: r[P2..P3]=NULL */ #define OP_SoftNull 60 /* synopsis: r[P1]=NULL */ #define OP_Blob 61 /* synopsis: r[P2]=P4 (len=P1) */ #define OP_Variable 62 /* synopsis: r[P2]=parameter(P1,P4) */ #define OP_Move 63 /* synopsis: r[P2@P3]=r[P1@P3] */ #define OP_Copy 64 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ #define OP_SCopy 65 /* synopsis: r[P2]=r[P1] */ #define OP_IntCopy 66 /* synopsis: r[P2]=r[P1] */ #define OP_ResultRow 67 /* synopsis: output=r[P1@P2] */ #define OP_CollSeq 68 #define OP_Function0 69 /* synopsis: r[P3]=func(r[P2@P5]) */ #define OP_Or 70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ #define OP_Function 72 /* synopsis: r[P3]=func(r[P2@P5]) */ #define OP_AddImm 73 /* synopsis: r[P1]=r[P1]+P2 */ #define OP_RealAffinity 74 #define OP_IsNull 75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ #define OP_NotNull 76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ #define OP_Ne 77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */ #define OP_Eq 78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */ #define OP_Gt 79 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */ #define OP_Le 80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */ #define OP_Lt 81 /* same as TK_LT, synopsis: IF r[P3]<r[P1] */ #define OP_Ge 82 /* same as TK_GE, synopsis: IF r[P3]>=r[P1] */ #define OP_ElseNotEq 83 /* same as TK_ESCAPE */ #define OP_BitAnd 84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ #define OP_BitOr 85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ #define OP_ShiftLeft 86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ #define OP_ShiftRight 87 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ #define OP_Add 88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ #define OP_Subtract 89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ #define OP_Multiply 90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ #define OP_Divide 91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ #define OP_Remainder 92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ #define OP_Concat 93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_Cast 94 /* synopsis: affinity(r[P1]) */ #define OP_BitNot 95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ #define OP_Permutation 96 #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_Compare 98 /* synopsis: r[P1@P3] <-> r[P2@P3] */ #define OP_Column 99 /* synopsis: r[P3]=PX */ #define OP_Affinity 100 /* synopsis: affinity(r[P1@P2]) */ #define OP_MakeRecord 101 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ #define OP_Count 102 /* synopsis: r[P2]=count() */ #define OP_ReadCookie 103 #define OP_SetCookie 104 #define OP_ReopenIdx 105 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenRead 106 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenWrite 107 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenDup 108 #define OP_OpenAutoindex 109 /* synopsis: nColumn=P2 */ #define OP_OpenEphemeral 110 /* synopsis: nColumn=P2 */ #define OP_SorterOpen 111 #define OP_SequenceTest 112 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 113 /* synopsis: P3 columns in r[P2] */ #define OP_Close 114 #define OP_ColumnsUsed 115 #define OP_Sequence 116 /* synopsis: r[P2]=cursor[P1].ctr++ */ #define OP_NewRowid 117 /* synopsis: r[P2]=rowid */ #define OP_Insert 118 /* synopsis: intkey=r[P3] data=r[P2] */ #define OP_InsertInt 119 /* synopsis: intkey=P3 data=r[P2] */ #define OP_Delete 120 #define OP_ResetCount 121 #define OP_SorterCompare 122 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ #define OP_SorterData 123 /* synopsis: r[P2]=data */ #define OP_RowData 124 /* synopsis: r[P2]=data */ #define OP_Rowid 125 /* synopsis: r[P2]=rowid */ #define OP_NullRow 126 #define OP_SorterInsert 127 /* synopsis: key=r[P2] */ #define OP_IdxInsert 128 /* synopsis: key=r[P2] */ #define OP_IdxDelete 129 /* synopsis: key=r[P2@P3] */ #define OP_DeferredSeek 130 /* synopsis: Move P3 to P1.rowid if needed */ #define OP_IdxRowid 131 /* synopsis: r[P2]=rowid */ #define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_Destroy 133 #define OP_Clear 134 #define OP_ResetSorter 135 #define OP_CreateIndex 136 /* synopsis: r[P2]=root iDb=P1 */ #define OP_CreateTable 137 /* synopsis: r[P2]=root iDb=P1 */ #define OP_SqlExec 138 #define OP_ParseSchema 139 #define OP_LoadAnalysis 140 #define OP_DropTable 141 #define OP_DropIndex 142 #define OP_DropTrigger 143 #define OP_IntegrityCk 144 #define OP_RowSetAdd 145 /* synopsis: rowset(P1)=r[P2] */ #define OP_Param 146 #define OP_FkCounter 147 /* synopsis: fkctr[P1]+=P2 */ #define OP_MemMax 148 /* synopsis: r[P1]=max(r[P1],r[P2]) */ #define OP_OffsetLimit 149 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ #define OP_AggStep0 150 /* synopsis: accum=r[P3] step(r[P2@P5]) */ #define OP_AggStep 151 /* synopsis: accum=r[P3] step(r[P2@P5]) */ #define OP_AggFinal 152 /* synopsis: accum=r[P1] N=P2 */ #define OP_Expire 153 #define OP_TableLock 154 /* synopsis: iDb=P1 root=P2 write=P3 */ #define OP_VBegin 155 #define OP_VCreate 156 #define OP_VDestroy 157 #define OP_VOpen 158 #define OP_VColumn 159 /* synopsis: r[P3]=vcolumn(P2) */ #define OP_VRename 160 #define OP_Pagecount 161 #define OP_MaxPgcnt 162 #define OP_CursorHint 163 #define OP_Noop 164 #define OP_Explain 165 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c ** are encoded into bitvectors as follows: */ #define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */ #define OPFLG_IN1 0x02 /* in1: P1 is an input */ ................................................................................ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\ /* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\ /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\ /* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\ /* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ /* 40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\ /* 48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\ /* 56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\ /* 64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\ /* 72 */ 0x00, 0x02, 0x02, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ /* 80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\ /* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x02, 0x12,\ /* 96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\ /* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 112 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04,\ /* 128 */ 0x04, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00,\ /* 136 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 144 */ 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00,\ /* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 160 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum ** JUMP opcode the better, so the mkopcodeh.tcl script that ** generated this include file strives to group all JUMP opcodes ** together near the beginning of the list. */ #define SQLITE_MX_JUMP_OPCODE 83 /* Maximum JUMP opcode */ /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ /* ** Additional non-public SQLITE_PREPARE_* flags */ ................................................................................ typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); #endif /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on ** each VDBE opcode. ** ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op ** comments in VDBE programs that show key decision points in the code ** generator. ................................................................................ /* Functions used to obtain and release page references. */ SQLITE_PRIVATE int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); SQLITE_PRIVATE void sqlite3PagerRef(DbPage*); SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*); SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*); /* Operations on page references. */ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*); SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*); SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); ................................................................................ ** Elements above, except pCache, are public. All that follow are ** private to pcache.c and should not be accessed by other modules. ** pCache is grouped with the public elements for efficiency. */ i16 nRef; /* Number of users of this page */ PgHdr *pDirtyNext; /* Next element in list of dirty pages */ PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ }; /* Bit values for PgHdr.flags */ #define PGHDR_CLEAN 0x001 /* Page not on the PCache.pDirty list */ #define PGHDR_DIRTY 0x002 /* Page is on the PCache.pDirty list */ #define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */ #define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before ................................................................................ SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); /* ** Functions for accessing sqlite3_vfs methods */ ................................................................................ ** DB_UnresetViews means that one or more views have column names that ** have been filled out. If the schema changes, these column names might ** changes and so the view will need to be reset. */ #define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ /* ** The number of different kinds of things that can be limited ** using the sqlite3_limit() interface. */ #define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) ................................................................................ ** schema information, the Lookaside.bEnabled flag is cleared so that ** lookaside allocations are not used to construct the schema objects. */ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ int nOut; /* Number of buffers currently checked out */ int mxOut; /* Highwater mark for nOut */ int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pFree; /* List of available buffers */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ }; struct LookasideSlot { LookasideSlot *pNext; /* Next buffer in the list of free buffers */ }; ................................................................................ struct sqlite3 { sqlite3_vfs *pVfs; /* OS Interface */ struct Vdbe *pVdbe; /* List of active virtual machines */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ sqlite3_mutex *mutex; /* Connection mutex */ Db *aDb; /* All backends */ int nDb; /* Number of backends currently in use */ int flags; /* Miscellaneous flags. See below */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 szMmap; /* Default mmap_size setting */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ int iSysErrno; /* Errno value from last system error */ u16 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ u8 autoCommit; /* The auto-commit flag. */ ................................................................................ #define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */ #define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ #define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */ #define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */ #define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */ #define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */ #define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */ #define SQLITE_EnableTrigger 0x00020000 /* True to enable triggers */ #define SQLITE_DeferFKs 0x00040000 /* Defer all FK constraints */ #define SQLITE_QueryOnly 0x00080000 /* Disable database changes */ #define SQLITE_CellSizeCk 0x00100000 /* Check btree cell sizes on load */ #define SQLITE_Fts3Tokenizer 0x00200000 /* Enable fts3_tokenizer(2) */ #define SQLITE_EnableQPSG 0x00400000 /* Query Planner Stability Guarantee */ /* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and ** could be factored out into a separate bit vector of the sqlite3 object. */ #define SQLITE_InternChanges 0x00800000 /* Uncommitted Hash table changes */ #define SQLITE_LoadExtFunc 0x01000000 /* Enable load_extension() SQL func */ #define SQLITE_PreferBuiltin 0x02000000 /* Preference to built-in funcs */ #define SQLITE_Vacuum 0x04000000 /* Currently in a VACUUM */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG #define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */ #define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */ #define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */ #define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */ #endif /* ** Bits of the sqlite3.dbOptFlags field that are used by the ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ #define SQLITE_QueryFlattener 0x0001 /* Query flattening */ #define SQLITE_ColumnCache 0x0002 /* Column cache */ #define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ #define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ /* not used 0x0010 // Was: SQLITE_IdxRealAsInt */ #define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ #define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ #define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ #define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ #define SQLITE_Transitive 0x0200 /* Transitive constraints */ #define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ #define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */ #define SQLITE_CountOfView 0x1000 /* The count-of-view optimization */ #define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */ #define SQLITE_AllOpts 0xffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) ................................................................................ ** VFUNCTION(zName, nArg, iArg, bNC, xFunc) ** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. ** ** DFUNCTION(zName, nArg, iArg, bNC, xFunc) ** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and ** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions ** and functions like sqlite_version() that can change, but not during ** a single query. ** ** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) ** Used to create an aggregate function definition implemented by ** the C functions xStep and xFinal. The first four parameters ** are interpreted in the same way as the first 4 parameters to ** FUNCTION(). ** ................................................................................ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ pArg, 0, xFunc, 0, #zName, } #define LIKEFUNC(zName, nArg, arg, flags) \ ................................................................................ ** Note that aSortOrder[] and aColl[] have nField+1 slots. There ** are nField slots for the columns of an index then one extra slot ** for the rowid at the end. */ struct KeyInfo { u32 nRef; /* Number of references to this KeyInfo object */ u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ u16 nField; /* Number of key columns in the index */ u16 nXField; /* Number of columns beyond the key columns */ sqlite3 *db; /* The database connection */ u8 *aSortOrder; /* Sort order for each column. */ CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; /* ** This object holds a record which has been parsed out into individual ................................................................................ */ struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ Mem *aMem; /* Values */ u16 nField; /* Number of entries in apMem[] */ i8 default_rc; /* Comparison result if keys are equal */ u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */ i8 r1; /* Value to return if (lhs > rhs) */ i8 r2; /* Value to return if (rhs < lhs) */ u8 eqSeen; /* True if an equality comparison has been seen */ }; /* ** Each SQL index is represented in memory by an ** instance of the following structure. ................................................................................ ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 op2; /* TK_REGISTER: original value of Expr.op ** TK_COLUMN: the value of p5 for OP_Column ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ Table *pTab; /* Table for TK_COLUMN expressions. */ }; /* ** The following are the meanings of bits in the Expr.flags field. */ #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ ................................................................................ ** column expression as it exists in a SELECT statement. However, if ** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name ** of the result column in the form: DATABASE.TABLE.COLUMN. This later ** form is used for name resolution with nested FROM clauses. */ struct ExprList { int nExpr; /* Number of expressions on the list */ int nAlloc; /* Number of a[] slots allocated */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ u8 sortOrder; /* 1 for DESC or 0 for ASC */ unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ ................................................................................ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int ckBase; /* Base register of data during check constraints */ int iSelfTab; /* Table of an index whose exprs are being coded */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ int iCacheCnt; /* Counter used to generate aColCache[].lru values */ int nLabel; /* Number of labels used */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ ................................................................................ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */ u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ ................................................................................ /* ** An objected used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. */ struct StrAccum { sqlite3 *db; /* Optional database for lookaside. Can be NULL */ char *zBase; /* A base allocation. Not from malloc. */ char *zText; /* The string collected so far */ u32 nChar; /* Length of the string so far */ u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ u8 printfFlags; /* SQLITE_PRINTF flags below */ }; #define STRACCUM_NOMEM 1 #define STRACCUM_TOOBIG 2 #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ ................................................................................ */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ int bOpenUri; /* True to interpret filenames as URIs */ int bUseCis; /* Use covering indices for full-scans */ int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ int nStmtSpill; /* Stmt-journal spill-to-disk threshold */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ void *pHeap; /* Heap storage space */ int nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max heap requests sizes */ sqlite3_int64 szMmap; /* mmap() space per open file */ sqlite3_int64 mxMmap; /* Maximum value for szMmap */ void *pScratch; /* Scratch memory */ int szScratch; /* Size of each scratch buffer */ int nScratch; /* Number of scratch buffers */ void *pPage; /* Page cache memory */ int szPage; /* Size of each page in pPage[] */ int nPage; /* Number of pages in pPage[] */ int mxParserStack; /* maximum depth of the parser stack */ int sharedCacheEnabled; /* true if shared-cache mode enabled */ u32 szPma; /* Maximum Sorter PMA size */ /* The above might be initialized to non-zero. The following need to always ................................................................................ SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*); SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*); SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*); #ifdef SQLITE_DEBUG SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); #endif /* ** Return code from the parse-tree walking primitives and their ** callbacks. ................................................................................ SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); SQLITE_PRIVATE int sqlite3MallocSize(void*); SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*); SQLITE_PRIVATE void *sqlite3ScratchMalloc(int); SQLITE_PRIVATE void sqlite3ScratchFree(void*); SQLITE_PRIVATE void *sqlite3PageMalloc(int); SQLITE_PRIVATE void sqlite3PageFree(void*); SQLITE_PRIVATE void sqlite3MemSetDefault(void); #ifndef SQLITE_UNTESTABLE SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); #endif SQLITE_PRIVATE int sqlite3HeapNearlyFull(void); ................................................................................ # define sqlite3MemoryBarrier() #endif SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int); SQLITE_PRIVATE void sqlite3StatusUp(int, int); SQLITE_PRIVATE void sqlite3StatusDown(int, int); SQLITE_PRIVATE void sqlite3StatusHighwater(int, int); /* Access to mutexes used by sqlite3_status() */ SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); #ifndef SQLITE_OMIT_FLOATING_POINT SQLITE_PRIVATE int sqlite3IsNaN(double); ................................................................................ #endif SQLITE_PRIVATE const char *sqlite3ErrStr(int); SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); ................................................................................ #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*); SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); #ifdef SQLITE_ENABLE_ATOMIC_WRITE SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); #endif SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p); SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *); SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); ................................................................................ #else # define sqlite3MemdebugSetType(X,Y) /* no-op */ # define sqlite3MemdebugHasType(X,Y) 1 # define sqlite3MemdebugNoType(X,Y) 1 #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ /* ** Threading interface */ #if SQLITE_MAX_WORKER_THREADS>0 SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); #endif #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST) SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*); #endif SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr); SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr); SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int); ................................................................................ */ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ SQLITE_USE_URI, /* bOpenUri */ SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ (void*)0, /* pHeap */ 0, /* nHeap */ 0, 0, /* mnHeap, mxHeap */ SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */ SQLITE_MAX_MMAP_SIZE, /* mxMmap */ (void*)0, /* pScratch */ 0, /* szScratch */ 0, /* nScratch */ (void*)0, /* pPage */ 0, /* szPage */ SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */ 0, /* mxParserStack */ 0, /* sharedCacheEnabled */ SQLITE_SORTER_PMASZ, /* szPma */ /* All the rest should always be initialized to zero */ ................................................................................ /* Cached OP_Column parse information is only valid if cacheStatus matches ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that ** the cache is out of date. */ u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 ** if there have been no prior seeks on the cursor. */ /* NB: seekResult does not distinguish between "no seeks have ever occurred ** on this cursor" and "the most recent seek was an exact match". */ /* When a new VdbeCursor is allocated, only the fields above are zeroed. ** The fields that follow are uninitialized, and must be individually ** initialized prior to first use. */ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ union { BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ u32 iHdrOffset; /* Offset to next unparsed byte of the header */ Pgno pgnoRoot; /* Root page of the open btree cursor */ i16 nField; /* Number of fields in the header */ u16 nHdrParsed; /* Number of header fields parsed so far */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ ................................................................................ ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. */ struct sqlite3_value { union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Used when bit MEM_Zero is set in flags */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ u8 eSubtype; /* Subtype for this value */ ................................................................................ */ #define MEMCELLSIZE offsetof(Mem,zMalloc) /* One or more of the following flags are set to indicate the validOK ** representations of the value stored in the Mem struct. ** ** If the MEM_Null flag is set, then the value is an SQL NULL value. ** No other flags may be set in this case. ** ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main ** database (see below for exceptions). If the MEM_Term flag is also ** set, then the string is nul terminated. The MEM_Int and MEM_Real ** flags may coexist with the MEM_Str flag. */ #define MEM_Null 0x0001 /* Value is NULL */ #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_AffMask 0x001f /* Mask of affinity bits */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0x81ff /* Mask of type bits */ /* Whenever Mem contains a valid string or blob representation, one of ** the following flags must be set to determine the memory management ** policy for Mem.z. The MEM_Term flag tells us whether or not the ** string is \000 or \u0000 terminated */ #define MEM_Term 0x0200 /* String rep is nul terminated */ #define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */ #define MEM_Static 0x0800 /* Mem.z points to a static string */ #define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ #define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ #define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ #define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */ #ifdef SQLITE_OMIT_INCRBLOB ................................................................................ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); #ifdef SQLITE_OMIT_FLOATING_POINT # define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 #else SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); #endif SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); ................................................................................ newValue = (sqlite3StatValueType)X; assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); assert( op>=0 && op<ArraySize(statMutex) ); assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex()) ); assert( op==SQLITE_STATUS_MALLOC_SIZE || op==SQLITE_STATUS_PAGECACHE_SIZE || op==SQLITE_STATUS_SCRATCH_SIZE || op==SQLITE_STATUS_PARSER_STACK ); if( newValue>wsdStat.mxValue[op] ){ wsdStat.mxValue[op] = newValue; } } /* ................................................................................ rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag); if( rc==0 ){ *pCurrent = (int)iCur; *pHighwater = (int)iHwtr; } return rc; } /* ** Query status information for a single database connection */ SQLITE_API int sqlite3_db_status( sqlite3 *db, /* The database connection whose status is desired */ int op, /* Status verb */ ................................................................................ if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){ return SQLITE_MISUSE_BKPT; } #endif sqlite3_mutex_enter(db->mutex); switch( op ){ case SQLITE_DBSTATUS_LOOKASIDE_USED: { *pCurrent = db->lookaside.nOut; *pHighwater = db->lookaside.mxOut; if( resetFlag ){ db->lookaside.mxOut = db->lookaside.nOut; } break; } case SQLITE_DBSTATUS_LOOKASIDE_HIT: case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { ................................................................................ DateTime *p ){ double r; if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ return setDateTimeToCurrent(context, p); }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ setRawDateNumber(p, r); return 0; } return 1; } ................................................................................ #ifndef SQLITE_OMIT_LOCALTIME case 'l': { /* localtime ** ** Assuming the current time value is UTC (a.k.a. GMT), shift it to ** show local time. */ if( sqlite3_stricmp(z, "localtime")==0 ){ computeJD(p); p->iJD += localtimeOffset(p, pCtx, &rc); clearYMD_HMS_TZ(p); } break; } #endif ................................................................................ p->iJD = (sqlite3_int64)r; p->validJD = 1; p->rawS = 0; rc = 0; } } #ifndef SQLITE_OMIT_LOCALTIME else if( sqlite3_stricmp(z, "utc")==0 ){ if( p->tzSet==0 ){ sqlite3_int64 c1; computeJD(p); c1 = localtimeOffset(p, pCtx, &rc); if( rc==SQLITE_OK ){ p->iJD -= c1; clearYMD_HMS_TZ(p); ................................................................................ ** This function registered all of the above C functions as SQL ** functions. This should be the only routine in this file with ** external linkage. */ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ static FuncDef aDateTimeFuncs[] = { #ifndef SQLITE_OMIT_DATETIME_FUNCS DFUNCTION(julianday, -1, 0, 0, juliandayFunc ), DFUNCTION(date, -1, 0, 0, dateFunc ), DFUNCTION(time, -1, 0, 0, timeFunc ), DFUNCTION(datetime, -1, 0, 0, datetimeFunc ), DFUNCTION(strftime, -1, 0, 0, strftimeFunc ), DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), DFUNCTION(current_date, 0, 0, 0, cdateFunc ), #else STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc), STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc), STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), ................................................................................ return id->pMethods->xWrite(id, pBuf, amt, offset); } SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){ return id->pMethods->xTruncate(id, size); } SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ DO_OS_MALLOC_TEST(id); return id->pMethods->xSync(id, flags); } SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ DO_OS_MALLOC_TEST(id); return id->pMethods->xFileSize(id, pSize); } SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ DO_OS_MALLOC_TEST(id); ................................................................................ SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){ int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); } SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ return id->pMethods->xDeviceCharacteristics(id); } SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ return id->pMethods->xShmLock(id, offset, n, flags); } SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){ id->pMethods->xShmBarrier(id); } SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ ................................................................................ int pgsz, int bExtend, /* True to extend file if necessary */ void volatile **pp /* OUT: Pointer to mapping */ ){ DO_OS_MALLOC_TEST(id); return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); } #if SQLITE_MAX_MMAP_SIZE>0 /* The real implementation of xFetch and xUnfetch */ SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ DO_OS_MALLOC_TEST(id); return id->pMethods->xFetch(id, iOff, iAmt, pp); } ................................................................................ ** is a no-op returning zero if SQLite is not compiled with ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ UNUSED_PARAMETER(n); return 0; #endif } /* ** An instance of the following object records the location of ** each unused scratch buffer. */ typedef struct ScratchFreeslot { struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ } ScratchFreeslot; /* ** State information local to the memory allocation subsystem. */ static SQLITE_WSD struct Mem0Global { sqlite3_mutex *mutex; /* Mutex to serialize access */ sqlite3_int64 alarmThreshold; /* The soft heap limit */ /* ** Pointers to the end of sqlite3GlobalConfig.pScratch memory ** (so that a range test can be used to determine if an allocation ** being freed came from pScratch) and a pointer to the list of ** unused scratch allocations. */ void *pScratchEnd; ScratchFreeslot *pScratchFree; u32 nScratchFree; /* ** True if heap is nearly "full" where "full" is defined by the ** sqlite3_soft_heap_limit() setting. */ int nearlyFull; } mem0 = { 0, 0, 0, 0, 0, 0 }; #define mem0 GLOBAL(struct Mem0Global, mem0) /* ** Return the memory allocator mutex. sqlite3_status() needs it. */ SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){ ................................................................................ SQLITE_PRIVATE int sqlite3MallocInit(void){ int rc; if( sqlite3GlobalConfig.m.xMalloc==0 ){ sqlite3MemSetDefault(); } memset(&mem0, 0, sizeof(mem0)); mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 && sqlite3GlobalConfig.nScratch>0 ){ int i, n, sz; ScratchFreeslot *pSlot; sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); sqlite3GlobalConfig.szScratch = sz; pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; n = sqlite3GlobalConfig.nScratch; mem0.pScratchFree = pSlot; mem0.nScratchFree = n; for(i=0; i<n-1; i++){ pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot); pSlot = pSlot->pNext; } pSlot->pNext = 0; mem0.pScratchEnd = (void*)&pSlot[1]; }else{ mem0.pScratchEnd = 0; sqlite3GlobalConfig.pScratch = 0; sqlite3GlobalConfig.szScratch = 0; sqlite3GlobalConfig.nScratch = 0; } if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 || sqlite3GlobalConfig.nPage<=0 ){ sqlite3GlobalConfig.pPage = 0; sqlite3GlobalConfig.szPage = 0; } rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0)); ................................................................................ SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return sqlite3Malloc(n); } /* ** Each thread may only have a single outstanding allocation from ** xScratchMalloc(). We verify this constraint in the single-threaded ** case by setting scratchAllocOut to 1 when an allocation ** is outstanding clearing it when the allocation is freed. */ #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) static int scratchAllocOut = 0; #endif /* ** Allocate memory that is to be used and released right away. ** This routine is similar to alloca() in that it is not intended ** for situations where the memory might be held long-term. This ** routine is intended to get memory to old large transient data ** structures that would not normally fit on the stack of an ** embedded processor. */ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ void *p; assert( n>0 ); sqlite3_mutex_enter(mem0.mutex); sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n); if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ p = mem0.pScratchFree; mem0.pScratchFree = mem0.pScratchFree->pNext; mem0.nScratchFree--; sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); sqlite3_mutex_leave(mem0.mutex); }else{ sqlite3_mutex_leave(mem0.mutex); p = sqlite3Malloc(n); if( sqlite3GlobalConfig.bMemstat && p ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); sqlite3_mutex_leave(mem0.mutex); } sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); } assert( sqlite3_mutex_notheld(mem0.mutex) ); #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch ** buffers per thread. ** ** This can only be checked in single-threaded mode. */ assert( scratchAllocOut==0 ); if( p ) scratchAllocOut++; #endif return p; } SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ if( p ){ #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) /* Verify that no more than two scratch allocation per thread ** is outstanding at one time. (This is only checked in the ** single-threaded case since checking in the multi-threaded case ** would be much more complicated.) */ assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); scratchAllocOut--; #endif if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){ /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */ ScratchFreeslot *pSlot; pSlot = (ScratchFreeslot*)p; sqlite3_mutex_enter(mem0.mutex); pSlot->pNext = mem0.pScratchFree; mem0.pScratchFree = pSlot; mem0.nScratchFree++; assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1); sqlite3_mutex_leave(mem0.mutex); }else{ /* Release memory back to the heap */ assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); if( sqlite3GlobalConfig.bMemstat ){ int iSize = sqlite3MallocSize(p); sqlite3_mutex_enter(mem0.mutex); sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ sqlite3GlobalConfig.m.xFree(p); } } } } /* ** TRUE if p is a lookaside memory allocation from db */ #ifndef SQLITE_OMIT_LOOKASIDE static int isLookaside(sqlite3 *db, void *p){ return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); } ................................................................................ LookasideSlot *pBuf = (LookasideSlot*)p; #ifdef 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_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); ................................................................................ assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); if( db->lookaside.bDisable==0 ){ assert( db->mallocFailed==0 ); if( n>db->lookaside.sz ){ db->lookaside.anStat[1]++; }else if( (pBuf = db->lookaside.pFree)==0 ){ db->lookaside.anStat[2]++; }else{ db->lookaside.pFree = pBuf->pNext; db->lookaside.nOut++; db->lookaside.anStat[0]++; if( db->lookaside.nOut>db->lookaside.mxOut ){ db->lookaside.mxOut = db->lookaside.nOut; } return (void*)pBuf; } }else if( db->mallocFailed ){ return 0; } #else assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); ................................................................................ bufpt = ""; }else if( xtype==etDYNSTRING ){ zExtra = bufpt; } if( precision>=0 ){ for(length=0; length<precision && bufpt[length]; length++){} }else{ length = sqlite3Strlen30(bufpt); } break; case etSQLESCAPE: /* Escape ' characters */ case etSQLESCAPE2: /* Escape ' and enclose in '...' */ case etSQLESCAPE3: { /* Escape " characters */ int i, j, k, n, isnull; int needQuote; ................................................................................ if( p->mxAlloc==0 ){ N = p->nAlloc - p->nChar - 1; setStrAccumError(p, STRACCUM_TOOBIG); return N; }else{ char *zOld = isMalloced(p) ? p->zText : 0; i64 szNew = p->nChar; assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); szNew += N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, ** to avoid having to call this routine too often */ szNew += p->nChar; } if( szNew > p->mxAlloc ){ ................................................................................ ** Append N copies of character c to the given string buffer. */ SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){ testcase( p->nChar + (i64)N > 0x7fffffff ); if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ return; } assert( (p->zText==p->zBase)==!isMalloced(p) ); while( (N--)>0 ) p->zText[p->nChar++] = c; } /* ** The StrAccum "p" is not large enough to accept N new bytes of z[]. ** So enlarge if first, then do the append. ** ................................................................................ */ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ N = sqlite3StrAccumEnlarge(p, N); if( N>0 ){ memcpy(&p->zText[p->nChar], z, N); p->nChar += N; } assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); } /* ** Append N bytes of text from z to the StrAccum object. Increase the ** size of the memory allocation for StrAccum if necessary. */ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ ................................................................................ /* ** Finish off a string by making sure it is zero-terminated. ** Return a pointer to the resulting string. Return a NULL ** pointer if any kind of error was encountered. */ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ assert( p->mxAlloc>0 && !isMalloced(p) ); p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ setStrAccumError(p, STRACCUM_NOMEM); } return p->zText; } SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ assert( (p->zText==p->zBase)==!isMalloced(p) ); p->zText[p->nChar] = 0; if( p->mxAlloc>0 && !isMalloced(p) ){ return strAccumFinishRealloc(p); } } return p->zText; } /* ** Reset an StrAccum string. Reclaim all malloced memory. */ SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); if( isMalloced(p) ){ sqlite3DbFree(p->db, p->zText); p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; } p->zText = 0; } ................................................................................ ** is malloced. ** n: Size of zBase in bytes. If total space requirements never exceed ** n then no memory allocations ever occur. ** mx: Maximum number of bytes to accumulate. If mx==0 then no memory ** allocations will ever occur. */ SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ p->zText = p->zBase = zBase; p->db = db; p->nChar = 0; p->nAlloc = n; p->mxAlloc = mx; p->accError = 0; p->printfFlags = 0; } /* ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. ................................................................................ result = s * scale; result *= 1.0e+308; } }else{ assert( e>=342 ); if( esign<0 ){ result = 0.0*s; }else{ result = 1e308*1e308*s; /* Infinity */ } } }else{ /* 1.0e+22 is the largest power of 10 than can be ** represented exactly. */ while( e%22 ) { scale *= 1.0e+1; e -= 1; } while( e>0 ) { scale *= 1.0e+22; e -= 22; } ................................................................................ return c; } /* ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This ** routine does *not* accept hexadecimal notation. ** ** If the zNum value is representable as a 64-bit twos-complement ** integer, then write that value into *pNum and return 0. ** ** If zNum is exactly 9223372036854775808, return 2. This special ** case is broken out because while 9223372036854775808 cannot be a ** signed 64-bit integer, its negative -9223372036854775808 can be. ** ** If zNum is too big for a 64-bit integer and is not ** 9223372036854775808 or if zNum contains any non-numeric text, ** then return 1. ** ** length is the number of bytes in the string (bytes, not characters). ** The string is not necessarily zero-terminated. The encoding is ** given by enc. */ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int incr; u64 u = 0; int neg = 0; /* assume positive */ int i; int c = 0; int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ const char *zStart; const char *zEnd = zNum + length; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); if( enc==SQLITE_UTF8 ){ incr = 1; }else{ incr = 2; ................................................................................ *pNum = (i64)u; } testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); if( &zNum[i]<zEnd /* Extra bytes at the end */ || (i==0 && zStart==zNum) /* No digits */ || i>19*incr /* Too many digits */ || nonNum /* UTF16 with high-order bytes non-zero */ ){ /* zNum is empty or contains non-numeric text or is longer ** than 19 digits (thus guaranteeing that it is too large) */ return 1; }else if( i<19*incr ){ /* Less than 19 digits, so we know that it fits in 64 bits */ assert( u<=LARGEST_INT64 ); return 0; }else{ /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */ c = compare2pow63(zNum, incr); if( c<0 ){ /* zNum is less than 9223372036854775808 so it fits */ assert( u<=LARGEST_INT64 ); return 0; }else if( c>0 ){ /* zNum is greater than 9223372036854775808 so it overflows */ return 1; }else{ /* zNum is exactly 9223372036854775808. Fits if negative. The ** special case 2 overflow if positive */ assert( u-1==LARGEST_INT64 ); return neg ? 0 : 2; } } } /* ** Transform a UTF-8 integer literal, in either decimal or hexadecimal, ** into a 64-bit signed integer. This routine accepts hexadecimal literals, ** whereas sqlite3Atoi64() does not. ** ** Returns: ** ** 0 Successful transformation. Fits in a 64-bit signed integer. ** 1 Integer too large for a 64-bit signed integer or is malformed ** 2 Special case of 9223372036854775808 */ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') ){ u64 u = 0; int i, k; for(i=2; z[i]=='0'; i++){} for(k=i; sqlite3Isxdigit(z[k]); k++){ u = u*16 + sqlite3HexToInt(z[k]); } memcpy(pOut, &u, 8); return (z[k]==0 && k-i<=16) ? 0 : 1; }else #endif /* SQLITE_OMIT_HEX_INTEGER */ { return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); } } ................................................................................ /* ** Attempt to add, substract, or multiply the 64-bit signed value iB against ** the other 64-bit signed integer at *pA and store the result in *pA. ** Return 0 on success. Or if the operation would have resulted in an ** overflow, leave *pA unchanged and return 1. */ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ #if GCC_VERSION>=5004000 return __builtin_add_overflow(*pA, iB, pA); #else i64 iA = *pA; testcase( iA==0 ); testcase( iA==1 ); testcase( iB==-1 ); testcase( iB==0 ); if( iB>=0 ){ testcase( iA>0 && LARGEST_INT64 - iA == iB ); ................................................................................ if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; } *pA += iB; return 0; #endif } SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ #if GCC_VERSION>=5004000 return __builtin_sub_overflow(*pA, iB, pA); #else testcase( iB==SMALLEST_INT64+1 ); if( iB==SMALLEST_INT64 ){ testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); if( (*pA)>=0 ) return 1; *pA -= iB; ................................................................................ return 0; }else{ return sqlite3AddInt64(pA, -iB); } #endif } SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ #if GCC_VERSION>=5004000 return __builtin_mul_overflow(*pA, iB, pA); #else i64 iA = *pA; if( iB>0 ){ if( iA>LARGEST_INT64/iB ) return 1; if( iA<SMALLEST_INT64/iB ) return 1; }else if( iB<0 ){ ................................................................................ SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; LogEst y = 40; if( x<8 ){ if( x<2 ) return 0; while( x<8 ){ y -= 10; x <<= 1; } }else{ while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ while( x>15 ){ y += 10; x >>= 1; } } return a[x&7] + y - 10; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Convert a double into a LogEst ................................................................................ /* 36 */ "Sort" OpHelp(""), /* 37 */ "Rewind" OpHelp(""), /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"), /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"), /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"), /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"), /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), /* 43 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 44 */ "Program" OpHelp(""), /* 45 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), /* 46 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), /* 47 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), /* 48 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 49 */ "IncrVacuum" OpHelp(""), /* 50 */ "VNext" OpHelp(""), /* 51 */ "Init" OpHelp("Start at P2"), /* 52 */ "Return" OpHelp(""), /* 53 */ "EndCoroutine" OpHelp(""), /* 54 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), /* 55 */ "Halt" OpHelp(""), /* 56 */ "Integer" OpHelp("r[P2]=P1"), /* 57 */ "Int64" OpHelp("r[P2]=P4"), /* 58 */ "String" OpHelp("r[P2]='P4' (len=P1)"), /* 59 */ "Null" OpHelp("r[P2..P3]=NULL"), /* 60 */ "SoftNull" OpHelp("r[P1]=NULL"), /* 61 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), /* 62 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), /* 63 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), /* 64 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), /* 65 */ "SCopy" OpHelp("r[P2]=r[P1]"), /* 66 */ "IntCopy" OpHelp("r[P2]=r[P1]"), /* 67 */ "ResultRow" OpHelp("output=r[P1@P2]"), /* 68 */ "CollSeq" OpHelp(""), /* 69 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), /* 70 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 71 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), /* 72 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), /* 73 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), /* 74 */ "RealAffinity" OpHelp(""), /* 75 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), /* 76 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), /* 77 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), /* 78 */ "Eq" OpHelp("IF r[P3]==r[P1]"), /* 79 */ "Gt" OpHelp("IF r[P3]>r[P1]"), /* 80 */ "Le" OpHelp("IF r[P3]<=r[P1]"), /* 81 */ "Lt" OpHelp("IF r[P3]<r[P1]"), /* 82 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), /* 83 */ "ElseNotEq" OpHelp(""), /* 84 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), /* 85 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), /* 86 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), /* 87 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), /* 88 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), /* 89 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), /* 90 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), /* 91 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), /* 92 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), /* 93 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 94 */ "Cast" OpHelp("affinity(r[P1])"), /* 95 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), /* 96 */ "Permutation" OpHelp(""), /* 97 */ "String8" OpHelp("r[P2]='P4'"), /* 98 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), /* 99 */ "Column" OpHelp("r[P3]=PX"), /* 100 */ "Affinity" OpHelp("affinity(r[P1@P2])"), /* 101 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), /* 102 */ "Count" OpHelp("r[P2]=count()"), /* 103 */ "ReadCookie" OpHelp(""), /* 104 */ "SetCookie" OpHelp(""), /* 105 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), /* 106 */ "OpenRead" OpHelp("root=P2 iDb=P3"), /* 107 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), /* 108 */ "OpenDup" OpHelp(""), /* 109 */ "OpenAutoindex" OpHelp("nColumn=P2"), /* 110 */ "OpenEphemeral" OpHelp("nColumn=P2"), /* 111 */ "SorterOpen" OpHelp(""), /* 112 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 113 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), /* 114 */ "Close" OpHelp(""), /* 115 */ "ColumnsUsed" OpHelp(""), /* 116 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), /* 117 */ "NewRowid" OpHelp("r[P2]=rowid"), /* 118 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), /* 119 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), /* 120 */ "Delete" OpHelp(""), /* 121 */ "ResetCount" OpHelp(""), /* 122 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), /* 123 */ "SorterData" OpHelp("r[P2]=data"), /* 124 */ "RowData" OpHelp("r[P2]=data"), /* 125 */ "Rowid" OpHelp("r[P2]=rowid"), /* 126 */ "NullRow" OpHelp(""), /* 127 */ "SorterInsert" OpHelp("key=r[P2]"), /* 128 */ "IdxInsert" OpHelp("key=r[P2]"), /* 129 */ "IdxDelete" OpHelp("key=r[P2@P3]"), /* 130 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), /* 131 */ "IdxRowid" OpHelp("r[P2]=rowid"), /* 132 */ "Real" OpHelp("r[P2]=P4"), /* 133 */ "Destroy" OpHelp(""), /* 134 */ "Clear" OpHelp(""), /* 135 */ "ResetSorter" OpHelp(""), /* 136 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), /* 137 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), /* 138 */ "SqlExec" OpHelp(""), /* 139 */ "ParseSchema" OpHelp(""), /* 140 */ "LoadAnalysis" OpHelp(""), /* 141 */ "DropTable" OpHelp(""), /* 142 */ "DropIndex" OpHelp(""), /* 143 */ "DropTrigger" OpHelp(""), /* 144 */ "IntegrityCk" OpHelp(""), /* 145 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), /* 146 */ "Param" OpHelp(""), /* 147 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), /* 148 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), /* 149 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), /* 150 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), /* 151 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), /* 152 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), /* 153 */ "Expire" OpHelp(""), /* 154 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), /* 155 */ "VBegin" OpHelp(""), /* 156 */ "VCreate" OpHelp(""), /* 157 */ "VDestroy" OpHelp(""), /* 158 */ "VOpen" OpHelp(""), /* 159 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), /* 160 */ "VRename" OpHelp(""), /* 161 */ "Pagecount" OpHelp(""), /* 162 */ "MaxPgcnt" OpHelp(""), /* 163 */ "CursorHint" OpHelp(""), /* 164 */ "Noop" OpHelp(""), /* 165 */ "Explain" OpHelp(""), }; return azName[i]; } #endif /************** End of opcodes.c *********************************************/ /************** Begin file os_unix.c *****************************************/ ................................................................................ /* ** standard include files. */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> /* #include <time.h> */ #include <sys/time.h> #include <errno.h> #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 # include <sys/mman.h> #endif #if SQLITE_ENABLE_LOCKING_STYLE # include <sys/ioctl.h> # include <sys/file.h> # include <sys/param.h> #endif /* SQLITE_ENABLE_LOCKING_STYLE */ #if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) # if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ ................................................................................ sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_MAX_MMAP_SIZE>0 int nFetchOut; /* Number of outstanding xFetch refs */ sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ void *pMapRegion; /* Memory mapped region */ #endif #ifdef __QNXNTO__ int sectorSize; /* Device sector size */ int deviceCharacteristics; /* Precomputed device characteristics */ #endif #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS ................................................................................ /* ** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek() ** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined. */ #ifdef __ANDROID__ # define lseek lseek64 #endif /* ** Different Unix systems declare open() in different ways. Same use ** open(const char*,int,mode_t). Others use open(const char*,int,...). ** The difference is important when using a pointer to the function. ** ** The safest way to deal with the problem is to always use this wrapper ................................................................................ #if defined(HAVE_LSTAT) { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, #else { "lstat", (sqlite3_syscall_ptr)0, 0 }, #endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) }; /* End of the overrideable system calls */ /* ** 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 ................................................................................ char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ #endif }; /* ** A lists of all unixInodeInfo objects. */ static unixInodeInfo *inodeList = 0; /* ** ** This function - unixLogErrorAtLine(), is only ever called via the macro ** unixLogError(). ** ** It is invoked after an error occurs in an OS function and errno has been ................................................................................ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; UnixUnusedFd *pNext; for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; robust_close(pFile, p->fd, __LINE__); sqlite3_free(p); } pInode->pUnused = 0; } /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** ................................................................................ if( pInode->pNext ){ assert( pInode->pNext->pPrev==pInode ); pInode->pNext->pPrev = pInode->pPrev; } sqlite3_free(pInode); } } } /* ** Given a file descriptor, locate the unixInodeInfo object that ** describes that file descriptor. Create a new one if necessary. The ** return value might be uninitialized if an error occurs. ** ................................................................................ memset(&fileId, 0, sizeof(fileId)); fileId.dev = statbuf.st_dev; #if OS_VXWORKS fileId.pId = pFile->pId; #else fileId.ino = (u64)statbuf.st_ino; #endif pInode = inodeList; while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ pInode = pInode->pNext; } if( pInode==0 ){ pInode = sqlite3_malloc64( sizeof(*pInode) ); if( pInode==0 ){ ................................................................................ /* ** Add the file descriptor used by file handle pFile to the corresponding ** pUnused list. */ static void setPendingFd(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p = pFile->pUnused; p->pNext = pInode->pUnused; pInode->pUnused = p; pFile->h = -1; pFile->pUnused = 0; } /* ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ................................................................................ osUnlink(pFile->zPath); sqlite3_free(*(char**)&pFile->zPath); pFile->zPath = 0; } #endif OSTRACE(("CLOSE %-3d\n", pFile->h)); OpenCounter(-1); sqlite3_free(pFile->pUnused); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } /* ** Close a file. */ ................................................................................ rc = lrc; } } } OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ rc = SQLITE_OK; reserved=1; } #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ *pResOut = reserved; return rc; } ................................................................................ } else { /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; } OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ rc = SQLITE_BUSY; } #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ return rc; } ................................................................................ failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 1); if( failed && (failed2 = afpSetLock(context->dbPath, pFile, SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ /* Can't reestablish the shared lock. Sqlite can't deal, this is ** a critical I/O error */ rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : SQLITE_IOERR_LOCK; goto afp_end_lock; } }else{ rc = failed; } } ................................................................................ assert( id ); assert( offset>=0 ); assert( amt>0 ); /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); #endif #if SQLITE_MAX_MMAP_SIZE>0 /* Deal with as much of this read request as possible by transfering ................................................................................ int wrote = 0; assert( id ); assert( amt>0 ); /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #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 ................................................................................ /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; } case SQLITE_FCNTL_LAST_ERRNO: { *(int*)pArg = pFile->lastErrno; return SQLITE_OK; ................................................................................ #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; int rc = SQLITE_OK; if( newLimit>sqlite3GlobalConfig.mxMmap ){ newLimit = sqlite3GlobalConfig.mxMmap; } *(i64*)pArg = pFile->mmapSizeMax; if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ pFile->mmapSizeMax = newLimit; if( pFile->mmapSize>0 ){ unixUnmapfile(pFile); rc = unixMapfile(pFile, -1); } ................................................................................ } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ } return SQLITE_NOTFOUND; } /* ** Return the sector size in bytes of the underlying block device for ** the specified file. This is almost always 512 bytes, but may be ** larger for some devices. ** ** SQLite code assumes this function cannot fail. It also assumes that ** if two files are created in the same file-system directory (i.e. ** a database and its journal file) that the sector size will be the ** same for both. */ #ifndef __QNXNTO__ static int unixSectorSize(sqlite3_file *NotUsed){ UNUSED_PARAMETER(NotUsed); return SQLITE_DEFAULT_SECTOR_SIZE; } #endif /* ** The following version of unixSectorSize() is optimized for QNX. */ #ifdef __QNXNTO__ #include <sys/dcmd_blk.h> #include <sys/statvfs.h> static int unixSectorSize(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; if( pFile->sectorSize == 0 ){ struct statvfs fsInfo; /* Set defaults for non-supported filesystems */ pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; pFile->deviceCharacteristics = 0; if( fstatvfs(pFile->h, &fsInfo) == -1 ) { ................................................................................ } /* Last chance verification. If the sector size isn't a multiple of 512 ** then it isn't valid.*/ if( pFile->sectorSize % 512 != 0 ){ pFile->deviceCharacteristics = 0; pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; } return pFile->sectorSize; } #endif /* __QNXNTO__ */ /* ** Return the device characteristics for the file. ** ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. ** However, that choice is controversial since technically the underlying ** file system does not always provide powersafe overwrites. (In other ................................................................................ ** written might end up being altered.) However, non-PSOW behavior is very, ** very rare. And asserting PSOW makes a large reduction in the amount ** of required I/O for journaling, since a lot of padding is eliminated. ** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control ** available to turn it off and URI query parameter available to turn it off. */ static int unixDeviceCharacteristics(sqlite3_file *id){ unixFile *p = (unixFile*)id; int rc = 0; #ifdef __QNXNTO__ if( p->sectorSize==0 ) unixSectorSize(id); rc = p->deviceCharacteristics; #endif if( p->ctrlFlags & UNIXFILE_PSOW ){ rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } return rc; } #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 /* ** Return the system page size. ** ................................................................................ ){ const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; assert( pNew->pInode==NULL ); /* Usually the path zFilename should not be a relative pathname. The ** exception is when opening the proxy "conch" file in builds that ** include the special Apple locking styles. */ #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE assert( zFilename==0 || zFilename[0]=='/' || pVfs->pAppData==(void*)&autolockIoFinder ); #else assert( zFilename==0 || zFilename[0]=='/' ); #endif /* No locking occurs in temporary files */ assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; pNew->pVfs = pVfs; pNew->zPath = zFilename; ................................................................................ /* Do not search for an unused file descriptor on vxworks. Not because ** vxworks would not benefit from the change (it might, we're not sure), ** but because no way to test it is currently available. It is better ** not to risk breaking vxworks support for the sake of such an obscure ** feature. */ #if !OS_VXWORKS struct stat sStat; /* Results of stat() call */ /* A stat() call may fail for various reasons. If this happens, it is ** almost certain that an open() call on the same path will also fail. ** For this reason, if an error occurs in the stat() call here, it is ** ignored and -1 is returned. The caller will try to open a new file ** descriptor on the same path, fail, and return an error to SQLite. ** ** Even if a subsequent open() call does succeed, the consequences of ** not searching for a reusable file descriptor are not dire. */ if( 0==osStat(zPath, &sStat) ){ unixInodeInfo *pInode; unixEnterMutex(); pInode = inodeList; while( pInode && (pInode->fileId.dev!=sStat.st_dev || pInode->fileId.ino!=(u64)sStat.st_ino) ){ pInode = pInode->pNext; } if( pInode ){ UnixUnusedFd **pp; for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ *pp = pUnused->pNext; } } unixLeaveMutex(); } #endif /* if !OS_VXWORKS */ return pUnused; } /* ** Find the mode, uid and gid of file zFile. */ ................................................................................ ** "<path to db>-walNN" ** ** where NN is a decimal number. The NN naming schemes are ** used by the test_multiplex.c module. */ nDb = sqlite3Strlen30(zPath) - 1; while( zPath[nDb]!='-' ){ #ifndef SQLITE_ENABLE_8_3_NAMES /* In the normal case (8+3 filenames disabled) the journal filename ** is guaranteed to contain a '-' character. */ assert( nDb>0 ); assert( sqlite3Isalnum(zPath[nDb]) ); #else /* If 8+3 names are possible, then the journal file might not contain ** a '-' character. So check for that case and return early. */ if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK; #endif nDb--; } memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; rc = getFileMode(zDb, pMode, pUid, pGid); }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ ................................................................................ fd = pUnused->fd; }else{ pUnused = sqlite3_malloc64(sizeof(*pUnused)); if( !pUnused ){ return SQLITE_NOMEM_BKPT; } } p->pUnused = pUnused; /* Database filenames are double-zero terminated if they are not ** URIs with parameters. Hence, they can always be passed into ** sqlite3_uri_parameter(). */ assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); }else if( !zName ){ ................................................................................ if( fd<0 ){ mode_t openMode; /* Permissions to create file with */ uid_t uid; /* Userid for the file */ gid_t gid; /* Groupid for the file */ rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); if( rc!=SQLITE_OK ){ assert( !p->pUnused ); assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); return rc; } fd = robust_open(zName, openFlags, openMode); OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); assert( !isExclusive || (openFlags & O_CREAT)!=0 ); if( fd<0 && errno!=EISDIR && isReadWrite ){ ................................................................................ } } assert( fd>=0 ); if( pOutFlags ){ *pOutFlags = flags; } if( p->pUnused ){ p->pUnused->fd = fd; p->pUnused->flags = flags; } if( isDelete ){ #if OS_VXWORKS zPath = zName; #elif defined(SQLITE_UNLINK_AFTER_CLOSE) zPath = sqlite3_mprintf("%s", zName); ................................................................................ } } goto open_finished; } } #endif rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); open_finished: if( rc!=SQLITE_OK ){ sqlite3_free(p->pUnused); } return rc; } /* ** Delete the file at zPath. If the dirSync argument is true, fsync() ................................................................................ memset(pNew, 0, sizeof(unixFile)); pNew->openFlags = openFlags; memset(&dummyVfs, 0, sizeof(dummyVfs)); dummyVfs.pAppData = (void*)&autolockIoFinder; dummyVfs.zName = "dummy"; pUnused->fd = fd; pUnused->flags = openFlags; pNew->pUnused = pUnused; rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); if( rc==SQLITE_OK ){ *ppFile = pNew; return SQLITE_OK; } end_create_proxy: ................................................................................ UNIXVFS("unix-proxy", proxyIoFinder ), #endif }; unsigned int i; /* Loop counter */ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ assert( ArraySize(aSyscall)==28 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ sqlite3_vfs_register(&aVfs[i], i==0); } return SQLITE_OK; } ................................................................................ #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; int rc = SQLITE_OK; if( newLimit>sqlite3GlobalConfig.mxMmap ){ newLimit = sqlite3GlobalConfig.mxMmap; } *(i64*)pArg = pFile->mmapSizeMax; if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ pFile->mmapSizeMax = newLimit; if( pFile->mmapSize>0 ){ winUnmapfile(pFile); rc = winMapfile(pFile, -1); } ................................................................................ }else{ attr = osGetFileAttributesA((char*)zConverted); #endif } return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); } /* ** Open a file. */ static int winOpen( sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ ................................................................................ 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 && winRetryIoerr(&cnt, &lastErrno) ){ /* Noop */ } #else while( (h = osCreateFileW((LPCWSTR)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL))==INVALID_HANDLE_VALUE && winRetryIoerr(&cnt, &lastErrno) ){ /* Noop */ } #endif } #ifdef SQLITE_WIN32_HAS_ANSI else{ while( (h = osCreateFileA((LPCSTR)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL))==INVALID_HANDLE_VALUE && winRetryIoerr(&cnt, &lastErrno) ){ /* Noop */ } } #endif winLogIoerr(cnt, __LINE__); OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); if( h==INVALID_HANDLE_VALUE ){ pFile->lastErrno = lastErrno; winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); sqlite3_free(zConverted); sqlite3_free(zTmpname); if( isReadWrite && !isExclusive ){ return winOpen(pVfs, zName, id, ((flags|SQLITE_OPEN_READONLY) & ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); }else{ return SQLITE_CANTOPEN_BKPT; } } if( pOutFlags ){ if( isReadWrite ){ *pOutFlags = SQLITE_OPEN_READWRITE; ................................................................................ UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); return nBuf; #else EntropyGatherer e; UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); #if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ #endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ e.a = (unsigned char*)zBuf; e.na = nBuf; e.nXor = 0; e.i = 0; { SYSTEMTIME x; osGetSystemTime(&x); ................................................................................ p->pDirty = pPage->pDirtyNext; assert( p->bPurgeable || p->eCreate==2 ); if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/ assert( p->bPurgeable==0 || p->eCreate==1 ); p->eCreate = 2; } } pPage->pDirtyNext = 0; pPage->pDirtyPrev = 0; } if( addRemove & PCACHE_DIRTYLIST_ADD ){ assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); pPage->pDirtyNext = p->pDirty; if( pPage->pDirtyNext ){ assert( pPage->pDirtyNext->pDirtyPrev==0 ); pPage->pDirtyNext->pDirtyPrev = pPage; }else{ p->pDirtyTail = pPage; if( p->bPurgeable ){ ................................................................................ */ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ assert( p->nRef>0 ); p->pCache->nRefSum--; if( (--p->nRef)==0 ){ if( p->flags&PGHDR_CLEAN ){ pcacheUnpin(p); }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/ /* Move the page to the head of the dirty list. If p->pDirtyPrev==0, ** then page p is already at the head of the dirty list and the ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE ** tag above. */ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); } } } /* ** Increase the reference count of a supplied page by 1. ................................................................................ ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of ** PgHdr1.pCache->szPage bytes is allocated directly before this structure ** in memory. */ struct PgHdr1 { sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ unsigned int iKey; /* Key value (page number) */ u8 isPinned; /* Page in use, not on the LRU list */ u8 isBulkLocal; /* This page from bulk local storage */ u8 isAnchor; /* This is the PGroup.lru element */ PgHdr1 *pNext; /* Next in hash table chain */ PCache1 *pCache; /* Cache that currently owns this page */ PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ }; /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set ** of one or more PCaches that are able to recycle each other's unpinned ** pages when they are under memory pressure. A PGroup is an instance of ** the following object. ** ** This page cache implementation works in one of two modes: ** ................................................................................ ** SQLITE_MUTEX_STATIC_LRU. */ struct PGroup { sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ unsigned int nMinPage; /* Sum of nMin for purgeable caches */ unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ unsigned int nCurrentPage; /* Number of purgeable pages allocated */ PgHdr1 lru; /* The beginning and end of the LRU list */ }; /* Each page cache is an instance of the following object. Every ** open database file (including each in-memory database and each ** temporary or transient database) has a single page cache which ** is an instance of this object. ** ** Pointers to structures of this type are cast and returned as ** opaque sqlite3_pcache* handles. */ struct PCache1 { /* Cache configuration parameters. Page size (szPage) and the purgeable ** flag (bPurgeable) are set when the cache is created. nMax may be ** modified at any time by a call to the pcache1Cachesize() method. ** The PGroup mutex must be held when accessing nMax. */ PGroup *pGroup; /* PGroup this cache belongs to */ int szPage; /* Size of database content section */ int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */ int szAlloc; /* Total size of one pcache line */ int bPurgeable; /* True if cache is purgeable */ unsigned int nMin; /* Minimum number of pages reserved */ unsigned int nMax; /* Configured "cache_size" value */ unsigned int n90pct; /* nMax*9/10 */ ................................................................................ ** This routine is called from sqlite3_initialize() and so it is guaranteed ** to be serialized already. There is no need for further mutexing. */ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ if( pcache1.isInit ){ PgFreeslot *p; if( pBuf==0 ) sz = n = 0; sz = ROUNDDOWN8(sz); pcache1.szSlot = sz; pcache1.nSlot = pcache1.nFreeSlot = n; pcache1.nReserve = n>90 ? 10 : (n/10 + 1); pcache1.pStart = pBuf; pcache1.pFree = 0; pcache1.bUnderPressure = 0; ................................................................................ #endif if( pPg==0 ) return 0; p->page.pBuf = pPg; p->page.pExtra = &p[1]; p->isBulkLocal = 0; p->isAnchor = 0; } if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage++; } return p; } /* ** Free a page object allocated by pcache1AllocPage(). */ static void pcache1FreePage(PgHdr1 *p){ ................................................................................ pCache->pFree = p; }else{ pcache1Free(p->page.pBuf); #ifdef SQLITE_PCACHE_SEPARATE_HEADER sqlite3_free(p); #endif } if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage--; } } /* ** Malloc function used by SQLite to obtain space from the buffer configured ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer ** exists, this function falls back to sqlite3Malloc(). */ ................................................................................ ** This function is used internally to remove the page pPage from the ** PGroup LRU list, if is part of it. If pPage is not part of the PGroup ** LRU list, then this function is a no-op. ** ** The PGroup mutex must be held when this function is called. */ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ PCache1 *pCache; assert( pPage!=0 ); assert( pPage->isPinned==0 ); pCache = pPage->pCache; assert( pPage->pLruNext ); assert( pPage->pLruPrev ); assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); pPage->pLruPrev->pLruNext = pPage->pLruNext; pPage->pLruNext->pLruPrev = pPage->pLruPrev; pPage->pLruNext = 0; pPage->pLruPrev = 0; pPage->isPinned = 1; assert( pPage->isAnchor==0 ); assert( pCache->pGroup->lru.isAnchor==1 ); pCache->nRecyclable--; return pPage; } /* ** Remove the page supplied as an argument from the hash table ** (PCache1.apHash structure) that it is currently stored in. ................................................................................ ** If there are currently more than nMaxPage pages allocated, try ** to recycle pages to reduce the number allocated to nMaxPage. */ static void pcache1EnforceMaxPage(PCache1 *pCache){ PGroup *pGroup = pCache->pGroup; PgHdr1 *p; assert( sqlite3_mutex_held(pGroup->mutex) ); while( pGroup->nCurrentPage>pGroup->nMaxPage && (p=pGroup->lru.pLruPrev)->isAnchor==0 ){ assert( p->pCache->pGroup==pGroup ); assert( p->isPinned==0 ); pcache1PinPage(p); pcache1RemoveFromHash(p, 1); } if( pCache->nPage==0 && pCache->pBulk ){ sqlite3_free(pCache->pBulk); pCache->pBulk = pCache->pFree = 0; } ................................................................................ PgHdr1 *pPage; assert( h<pCache->nHash ); pp = &pCache->apHash[h]; while( (pPage = *pp)!=0 ){ if( pPage->iKey>=iLimit ){ pCache->nPage--; *pp = pPage->pNext; if( !pPage->isPinned ) pcache1PinPage(pPage); pcache1FreePage(pPage); }else{ pp = &pPage->pNext; TESTONLY( if( nPage>=0 ) nPage++; ) } } if( h==iStop ) break; ................................................................................ pCache->bPurgeable = (bPurgeable ? 1 : 0); pcache1EnterMutex(pGroup); pcache1ResizeHash(pCache); if( bPurgeable ){ pCache->nMin = 10; pGroup->nMinPage += pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; } pcache1LeaveMutex(pGroup); if( pCache->nHash==0 ){ pcache1Destroy((sqlite3_pcache*)pCache); pCache = 0; } } ................................................................................ /* Step 4. Try to recycle a page. */ if( pCache->bPurgeable && !pGroup->lru.pLruPrev->isAnchor && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache)) ){ PCache1 *pOther; pPage = pGroup->lru.pLruPrev; assert( pPage->isPinned==0 ); pcache1RemoveFromHash(pPage, 0); pcache1PinPage(pPage); pOther = pPage->pCache; if( pOther->szAlloc != pCache->szAlloc ){ pcache1FreePage(pPage); pPage = 0; }else{ pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); } } /* Step 5. If a usable page buffer has still not been found, ** attempt to allocate a new one. */ if( !pPage ){ ................................................................................ unsigned int h = iKey % pCache->nHash; pCache->nPage++; pPage->iKey = iKey; pPage->pNext = pCache->apHash[h]; pPage->pCache = pCache; pPage->pLruPrev = 0; pPage->pLruNext = 0; pPage->isPinned = 1; *(void **)pPage->page.pExtra = 0; pCache->apHash[h] = pPage; if( iKey>pCache->iMaxKey ){ pCache->iMaxKey = iKey; } } return pPage; ................................................................................ while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } /* Step 2: If the page was found in the hash table, then return it. ** If the page was not in the hash table and createFlag is 0, abort. ** Otherwise (page not in hash and createFlag!=0) continue with ** subsequent steps to try to create the page. */ if( pPage ){ if( !pPage->isPinned ){ return pcache1PinPage(pPage); }else{ return pPage; } }else if( createFlag ){ /* Steps 3, 4, and 5 implemented by this subroutine */ return pcache1FetchStage2(pCache, iKey, createFlag); ................................................................................ assert( pPage->pCache==pCache ); pcache1EnterMutex(pGroup); /* It is an error to call this function if the page is already ** part of the PGroup LRU list. */ assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); assert( pPage->isPinned==1 ); if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ pcache1RemoveFromHash(pPage, 1); }else{ /* Add the page to the PGroup LRU list. */ PgHdr1 **ppFirst = &pGroup->lru.pLruNext; pPage->pLruPrev = &pGroup->lru; (pPage->pLruNext = *ppFirst)->pLruPrev = pPage; *ppFirst = pPage; pCache->nRecyclable++; pPage->isPinned = 0; } pcache1LeaveMutex(pCache->pGroup); } /* ** Implementation of the sqlite3_pcache.xRekey method. ................................................................................ && (p=pcache1.grp.lru.pLruPrev)!=0 && p->isAnchor==0 ){ nFree += pcache1MemSize(p->page.pBuf); #ifdef SQLITE_PCACHE_SEPARATE_HEADER nFree += sqlite3MemSize(p); #endif assert( p->isPinned==0 ); pcache1PinPage(p); pcache1RemoveFromHash(p, 1); } pcache1LeaveMutex(&pcache1.grp); } return nFree; } ................................................................................ int *pnMax, /* OUT: Global maximum cache size */ int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ int *pnRecyclable /* OUT: Total number of pages available for recycling */ ){ PgHdr1 *p; int nRecyclable = 0; for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){ assert( p->isPinned==0 ); nRecyclable++; } *pnCurrent = pcache1.grp.nCurrentPage; *pnMax = (int)pcache1.grp.nMaxPage; *pnMin = (int)pcache1.grp.nMinPage; *pnRecyclable = nRecyclable; } #endif /************** End of pcache1.c *********************************************/ ................................................................................ */ #ifndef SQLITE_WAL_H #define SQLITE_WAL_H /* #include "sqliteInt.h" */ /* Additional values that can be added to the sync_flags argument of ** sqlite3WalFrames(): */ #define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ #define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalLimit(x,y) # define sqlite3WalClose(v,w,x,y,z) 0 # define sqlite3WalBeginReadTransaction(y,z) 0 # define sqlite3WalEndReadTransaction(z) ................................................................................ ** The following two macros are used within the PAGERTRACE() macros above ** to print out file-descriptors. ** ** PAGERID() takes a pointer to a Pager struct as its argument. The ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file ** struct as its argument. */ #define PAGERID(p) ((int)(p->fd)) #define FILEHANDLEID(fd) ((int)fd) /* ** The Pager.eState variable stores the current 'state' of a pager. A ** pager may be in any one of the seven states shown in the following ** state diagram. ** ** OPEN <------+------+ ................................................................................ ** ** errCode ** ** The Pager.errCode variable is only ever used in PAGER_ERROR state. It ** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode ** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX ** sub-codes. */ struct Pager { sqlite3_vfs *pVfs; /* OS functions to use for IO */ u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ u8 useJournal; /* Use a rollback journal on this file */ u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 extraSync; /* sync directory after journal delete */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary or immutable file */ u8 noLock; /* Do not lock (except in WAL mode) */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ /************************************************************************** ** The following block contains those class members that change during ................................................................................ assert( p->eLock==EXCLUSIVE_LOCK ); assert( pPager->errCode==SQLITE_OK ); assert( !pagerUseWal(pPager) ); assert( p->eLock>=EXCLUSIVE_LOCK ); assert( isOpen(p->jfd) || p->journalMode==PAGER_JOURNALMODE_OFF || p->journalMode==PAGER_JOURNALMODE_WAL ); assert( pPager->dbOrigSize<=pPager->dbHintSize ); break; case PAGER_WRITER_FINISHED: assert( p->eLock==EXCLUSIVE_LOCK ); assert( pPager->errCode==SQLITE_OK ); assert( !pagerUseWal(pPager) ); assert( isOpen(p->jfd) || p->journalMode==PAGER_JOURNALMODE_OFF || p->journalMode==PAGER_JOURNALMODE_WAL ); break; case PAGER_ERROR: /* There must be at least one outstanding reference to the pager if ** in ERROR state. Otherwise the pager should have already dropped ** back to OPEN state. ................................................................................ IOTRACE(("LOCK %p %d\n", pPager, eLock)) } } return rc; } /* ** This function determines whether or not the atomic-write optimization ** can be used with this pager. The optimization can be used if: ** ** (a) the value returned by OsDeviceCharacteristics() indicates that ** a database page may be written atomically, and ** (b) the value returned by OsSectorSize() is less than or equal ** to the page size. ** ** The optimization is also always enabled for temporary files. It is ** an error to call this function if pPager is opened on an in-memory ** database. ** ** If the optimization cannot be used, 0 is returned. If it can be used, ** then the value returned is the size of the journal file when it ** contains rollback data for exactly one page. */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE static int jrnlBufferSize(Pager *pPager){ assert( !MEMDB ); if( !pPager->tempFile ){ int dc; /* Device characteristics */ int nSector; /* Sector size */ int szPage; /* Page size */ assert( isOpen(pPager->fd) ); dc = sqlite3OsDeviceCharacteristics(pPager->fd); nSector = pPager->sectorSize; szPage = pPager->pageSize; assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){ return 0; } } return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); } #else # define jrnlBufferSize(x) 0 #endif /* ** If SQLITE_CHECK_PAGES is defined then we do some sanity checking ** on the cache using a hash function. This is used for testing ** and debugging only. */ #ifdef SQLITE_CHECK_PAGES ................................................................................ unsigned char aMagic[8]; /* A buffer to hold the magic header */ zMaster[0] = '\0'; if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) || szJ<16 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) || len>=nMaster || len==0 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) || memcmp(aMagic, aJournalMagic, 8) || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len)) ){ return rc; ................................................................................ assert( assert_pager_state(pPager) ); assert( pPager->eState!=PAGER_ERROR ); if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){ return SQLITE_OK; } releaseAllSavepoints(pPager); assert( isOpen(pPager->jfd) || pPager->pInJournal==0 ); if( isOpen(pPager->jfd) ){ assert( !pagerUseWal(pPager) ); /* Finalize the journal file. */ if( sqlite3JournalIsInMemory(pPager->jfd) ){ /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */ sqlite3OsClose(pPager->jfd); ................................................................................ u32 u; /* Unsigned loop counter */ Pgno mxPg = 0; /* Size of the original file in pages */ int rc; /* Result code of a subroutine */ int res = 1; /* Value returned by sqlite3OsAccess() */ char *zMaster = 0; /* Name of master journal file if any */ int needPagerReset; /* True to reset page prior to first page rollback */ int nPlayback = 0; /* Total number of pages restored from journal */ /* Figure out how many records are in the journal. Abort early if ** the journal is empty. */ assert( isOpen(pPager->jfd) ); rc = sqlite3OsFileSize(pPager->jfd, &szJ); if( rc!=SQLITE_OK ){ ................................................................................ } } } /*NOTREACHED*/ assert( 0 ); end_playback: /* Following a rollback, the database file should be back in its original ** state prior to the start of the transaction, so invoke the ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the ** assertion that the transaction counter was modified. */ #ifdef SQLITE_DEBUG if( pPager->fd->pMethods ){ ................................................................................ */ setSectorSize(pPager); return rc; } /* ** Read the content for page pPg out of the database file and into ** pPg->pData. A shared lock or greater must be held on the database ** file before this function is called. ** ** If page 1 is read, then the value of Pager.dbFileVers[] is set to ** the value read from the database file. ** ** If an IO error occurs, then the IO error is returned to the caller. ** Otherwise, SQLITE_OK is returned. */ static int readDbPage(PgHdr *pPg, u32 iFrame){ Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ Pgno pgno = pPg->pgno; /* Page number to read */ int rc = SQLITE_OK; /* Return code */ int pgsz = pPager->pageSize; /* Number of bytes to read */ assert( pPager->eState>=PAGER_READER && !MEMDB ); assert( isOpen(pPager->fd) ); #ifndef SQLITE_OMIT_WAL if( iFrame ){ /* Try to pull the page from the write-ahead log. */ rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); }else #endif { i64 iOffset = (pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } } if( pgno==1 ){ if( rc ){ /* If the read is unsuccessful, set the dbFileVers[] to something ** that will never be a valid file version. dbFileVers[] is a copy ** of bytes 24..39 of the database. Bytes 28..31 should always be ** zero or the size of the database in page. Bytes 32..35 and 35..39 ** should be page numbers which are never 0xffffffff. So filling ** pPager->dbFileVers[] with all 0xff bytes should suffice. ................................................................................ */ memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); }else{ u8 *dbFileVers = &((u8*)pPg->pData)[24]; memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); } } CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT); PAGER_INCR(sqlite3_pager_readdb_count); PAGER_INCR(pPager->nRead); IOTRACE(("PGIN %p %d\n", pPager, pgno)); PAGERTRACE(("FETCH %d page %d hash(%08x)\n", PAGERID(pPager), pgno, pager_pagehash(pPg))); return rc; } /* ** Update the value of the change-counter at offsets 24 and 92 in ** the header and the sqlite version number at offset 96. ................................................................................ assert( pagerUseWal(pPager) ); pPg = sqlite3PagerLookup(pPager, iPg); if( pPg ){ if( sqlite3PcachePageRefcount(pPg)==1 ){ sqlite3PcacheDrop(pPg); }else{ u32 iFrame = 0; rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); if( rc==SQLITE_OK ){ rc = readDbPage(pPg, iFrame); } if( rc==SQLITE_OK ){ pPager->xReiniter(pPg); } sqlite3PagerUnrefNotNull(pPg); } } ................................................................................ }else{ pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0; pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0; pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0; } if( pPager->noSync ){ pPager->syncFlags = 0; pPager->ckptSyncFlags = 0; }else if( pgFlags & PAGER_FULLFSYNC ){ pPager->syncFlags = SQLITE_SYNC_FULL; pPager->ckptSyncFlags = SQLITE_SYNC_FULL; }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->ckptSyncFlags = SQLITE_SYNC_FULL; }else{ pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } pPager->walSyncFlags = pPager->syncFlags; if( pPager->fullSync ){ pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; } if( pgFlags & PAGER_CACHESPILL ){ pPager->doNotSpill &= ~SPILLFLAG_OFF; }else{ pPager->doNotSpill |= SPILLFLAG_OFF; } } ................................................................................ disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); pagerFreeMapHdrs(pPager); /* pPager->errCode = 0; */ pPager->exclusiveMode = 0; #ifndef SQLITE_OMIT_WAL assert( db || pPager->pWal==0 ); sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp) ); pPager->pWal = 0; #endif pager_reset(pPager); if( MEMDB ){ pager_unlock(pPager); ................................................................................ if( pagerUseWal(pPager) ){ /* Write a single frame for this page to the log. */ rc = subjournalPageIfRequired(pPg); if( rc==SQLITE_OK ){ rc = pagerWalFrames(pPager, pPg, 0, 0); } }else{ /* Sync the journal file if required. */ if( pPg->flags&PGHDR_NEED_SYNC || pPager->eState==PAGER_WRITER_CACHEMOD ){ rc = syncJournal(pPager, 1); } ................................................................................ assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; if( pPager->noSync ){ assert( pPager->fullSync==0 ); assert( pPager->extraSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; pPager->extraSync = 0; pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ pPager->nExtra = (u16)nExtra; pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; assert( isOpen(pPager->fd) || tempFile ); ................................................................................ ** transaction and unlock the pager. ** ** Except, in locking_mode=EXCLUSIVE when there is nothing to in ** the rollback journal, the unlock is not performed and there is ** nothing to rollback, so this routine is a no-op. */ static void pagerUnlockIfUnused(Pager *pPager){ if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ pagerUnlockAndRollback(pPager); } } /* ** The page getter methods each try to acquire a reference to a ** page with page number pgno. If the requested reference is ................................................................................ TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno); testcase( rc==SQLITE_NOMEM ); sqlite3EndBenignMalloc(); } memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ u32 iFrame = 0; /* Frame to read from WAL file */ if( pagerUseWal(pPager) ){ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); if( rc!=SQLITE_OK ) goto pager_acquire_err; } assert( pPg->pPager==pPager ); pPager->aStat[PAGER_STAT_MISS]++; rc = readDbPage(pPg, iFrame); if( rc!=SQLITE_OK ){ goto pager_acquire_err; } } pager_set_pagehash(pPg); } return SQLITE_OK; ................................................................................ if( pPage==0 ) return 0; return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); } /* ** Release a page reference. ** ** If the number of references to the page drop to zero, then the ** page is added to the LRU list. When all references to all pages ** are released, a rollback occurs and the lock on the database is ** removed. */ SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ Pager *pPager; assert( pPg!=0 ); pPager = pPg->pPager; if( pPg->flags & PGHDR_MMAP ){ pagerReleaseMapPage(pPg); }else{ sqlite3PcacheRelease(pPg); } pagerUnlockIfUnused(pPager); } SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ if( pPg ) sqlite3PagerUnrefNotNull(pPg); } /* ** This function is called at the start of every write transaction. ** There must already be a RESERVED or EXCLUSIVE lock on the database ** file when this routine is called. ** ................................................................................ rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); } sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ sqlite3PcacheCleanAll(pPager->pPCache); } }else{ /* The following block updates the change-counter. Exactly how it ** does this depends on whether or not the atomic-update optimization ** was enabled at compile time, and if this transaction meets the ** runtime criteria to use the operation: ** ** * The file-system supports the atomic-write property for ** blocks of size page-size, and ................................................................................ ** mode. ** ** Otherwise, if the optimization is both enabled and applicable, ** then call pager_incr_changecounter() to update the change-counter ** in 'direct' mode. In this case the journal file will never be ** created for this transaction. */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE PgHdr *pPg; assert( isOpen(pPager->jfd) || pPager->journalMode==PAGER_JOURNALMODE_OFF || pPager->journalMode==PAGER_JOURNALMODE_WAL ); if( !zMaster && isOpen(pPager->jfd) && pPager->journalOff==jrnlBufferSize(pPager) && pPager->dbSize>=pPager->dbOrigSize && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) ){ /* Update the db file change counter via the direct-write method. The ** following call will modify the in-memory representation of page 1 ** to include the updated change counter and then write page 1 ** directly to the database file. Because of the atomic-write ** property of the host file-system, this is safe. */ rc = pager_incr_changecounter(pPager, 1); }else{ rc = sqlite3JournalCreate(pPager->jfd); if( rc==SQLITE_OK ){ rc = pager_incr_changecounter(pPager, 0); } } #else rc = pager_incr_changecounter(pPager, 0); #endif if( rc!=SQLITE_OK ) goto commit_phase_one_exit; /* Write the master journal name into the journal file. If a master ** journal file name has already been written to the journal file, ** or if zMaster is NULL (no master journal), then this call is a no-op. */ rc = writeMasterJournal(pPager, zMaster); ................................................................................ ** journal requires a sync here. However, in locking_mode=exclusive ** on a system under memory pressure it is just possible that this is ** not the case. In this case it is likely enough that the redundant ** xSync() call will be changed to a no-op by the OS anyhow. */ rc = syncJournal(pPager, 0); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); if( rc!=SQLITE_OK ){ assert( rc!=SQLITE_IOERR_BLOCKED ); goto commit_phase_one_exit; } sqlite3PcacheCleanAll(pPager->pPCache); /* If the file on disk is smaller than the database image, use ................................................................................ int *pnCkpt /* OUT: Final number of checkpointed frames */ ){ int rc = SQLITE_OK; if( pPager->pWal ){ rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), pPager->pBusyHandlerArg, pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, pnLog, pnCkpt ); } return rc; } SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ ................................................................................ /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on ** the database file, the log and log-summary files will be deleted. */ if( rc==SQLITE_OK && pPager->pWal ){ rc = pagerExclusiveLock(pPager); if( rc==SQLITE_OK ){ rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, (u8*)pPager->pTmpSpace); pPager->pWal = 0; pagerFixMaplimit(pPager); if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); } } return rc; ................................................................................ ){ i64 nSize; /* Current size of database file */ u32 nBackfill = pInfo->nBackfill; pInfo->nBackfillAttempted = mxSafeFrame; /* Sync the WAL to disk */ if( sync_flags ){ rc = sqlite3OsSync(pWal->pWalFd, sync_flags); } /* If the database may grow as a result of this checkpoint, hint ** about the eventual size of the db file to the VFS layer. */ if( rc==SQLITE_OK ){ i64 nReq = ((i64)mxPage * szPage); rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); ................................................................................ /* If work was actually accomplished... */ if( rc==SQLITE_OK ){ if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ i64 szDb = pWal->hdr.nPage*(i64)szPage; testcase( IS_BIG_INT(szDb) ); rc = sqlite3OsTruncate(pWal->pDbFd, szDb); if( rc==SQLITE_OK && sync_flags ){ rc = sqlite3OsSync(pWal->pDbFd, sync_flags); } } if( rc==SQLITE_OK ){ pInfo->nBackfill = mxSafeFrame; } } ................................................................................ if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ int iFirstAmt = (int)(p->iSyncPoint - iOffset); rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); if( rc ) return rc; iOffset += iFirstAmt; iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK); if( iAmt==0 || rc ) return rc; } rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); return rc; } /* ................................................................................ } /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise ** an out-of-order write following a WAL restart could result in ** database corruption. See the ticket: ** ** http://localhost:591/sqlite/info/ff5be73dee */ if( pWal->syncHeader && sync_flags ){ rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); if( rc ) return rc; } } assert( (int)pWal->szPage==szPage ); /* Setup information needed to write frames into the WAL */ w.pWal = pWal; ................................................................................ ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not ** needed and only the sync is done. If padding is needed, then the ** final frame is repeated (with its commit mark) until the next sector ** boundary is crossed. Only the part of the WAL prior to the last ** sector boundary is synced; the part of the last frame that extends ** past the sector boundary is written after the sync. */ if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ int bSync = 1; if( pWal->padToSectorBoundary ){ int sectorSize = sqlite3SectorSize(pWal->pWalFd); w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; bSync = (w.iSyncPoint==iOffset); testcase( bSync ); while( iOffset<w.iSyncPoint ){ ................................................................................ if( rc ) return rc; iOffset += szFrame; nExtra++; } } if( bSync ){ assert( rc==SQLITE_OK ); rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } } /* If this frame set completes the first transaction in the WAL and ** if PRAGMA journal_size_limit is set, then truncate the WAL to the ** journal size limit, if possible. */ ................................................................................ ** ** skipNext meaning: ** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op. ** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op. ** eState==FAULT: Cursor fault with skipNext as error code. */ struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ BtShared *pBt; /* The BtShared this cursor points to */ BtCursor *pNext; /* Forms a linked list of all cursors */ Pgno *aOverflow; /* Cache of overflow page locations */ CellInfo info; /* A parse of the cell we are pointing at */ i64 nKey; /* Size of pKey, or last integer key */ void *pKey; /* Saved key that was cursor last known position */ Pgno pgnoRoot; /* The root page of this tree */ int nOvflAlloc; /* Allocated size of aOverflow[] array */ int skipNext; /* Prev() is noop if negative. Next() is noop if positive. ** Error code if eState==CURSOR_FAULT */ u8 curFlags; /* zero or more BTCF_* flags defined below */ u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ u8 hints; /* As configured by CursorSetHints() */ /* All fields above are zeroed when the cursor is allocated. See ** sqlite3BtreeCursorZero(). Fields that follow must be manually ** initialized. */ i8 iPage; /* Index of current page in apPage */ u8 curIntKey; /* Value of apPage[0]->intKey */ u16 ix; /* Current index for apPage[iPage] */ u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ }; /* ** Legal values for BtCursor.curFlags */ #define BTCF_WriteFlag 0x01 /* True if a write cursor */ #define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ ................................................................................ pLock->eLock = READ_LOCK; } } } #endif /* SQLITE_OMIT_SHARED_CACHE */ static void releasePage(MemPage *pPage); /* Forward reference */ /* ***** This routine is used inside of assert() only **** ** ** Verify that the cursor holds the mutex on its BtShared */ #ifdef SQLITE_DEBUG ................................................................................ } /* ** Release all of the apPage[] pages for a cursor. */ static void btreeReleaseAllCursorPages(BtCursor *pCur){ int i; for(i=0; i<=pCur->iPage; i++){ releasePage(pCur->apPage[i]); pCur->apPage[i] = 0; } pCur->iPage = -1; } /* ** The cursor passed as the only argument must point to a valid entry ** when this function is called (i.e. have eState==CURSOR_VALID). This ** function saves the current cursor key in variables pCur->nKey and ** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error ................................................................................ if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ int rc = saveCursorPosition(p); if( SQLITE_OK!=rc ){ return rc; } }else{ testcase( p->iPage>0 ); btreeReleaseAllCursorPages(p); } } p = p->pNext; }while( p ); return SQLITE_OK; } ................................................................................ if( pKey ){ assert( nKey==(i64)(int)nKey ); pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo); if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); if( pIdxKey->nField==0 ){ rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno); goto moveto_done; } }else{ pIdxKey = 0; } rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); moveto_done: ................................................................................ ** ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor ** back to where it ought to be if this routine returns true. */ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ return pCur->eState!=CURSOR_VALID; } /* ** This routine restores a cursor back to its original position after it ** has been moved by some outside activity (such as a btree rebalance or ** a row having been deleted out from under the cursor). ** ** On success, the *pDifferentRow parameter is false if the cursor is left ................................................................................ if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ u8 *pEnd = &data[cellOffset + nCell*2]; u8 *pAddr; int sz2 = 0; int sz = get2byte(&data[iFree+2]); int top = get2byte(&data[hdr+5]); if( iFree2 ){ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); sz2 = get2byte(&data[iFree2+2]); assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize ); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; } cbrk = top+sz; assert( cbrk+(iFree-top) <= usableSize ); ................................................................................ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ const int hdr = pPg->hdrOffset; u8 * const aData = pPg->aData; int iAddr = hdr + 1; int pc = get2byte(&aData[iAddr]); int x; int usableSize = pPg->pBt->usableSize; assert( pc>0 ); do{ int size; /* Size of the free slot */ /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of ** increasing offset. */ if( pc>usableSize-4 || pc<iAddr+4 ){ *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno); return 0; } /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each ** freeblock form a big-endian integer which is the size of the freeblock ** in bytes, including the 4-byte header. */ size = get2byte(&aData[pc+2]); if( (x = size - nByte)>=0 ){ testcase( x==4 ); testcase( x==3 ); if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){ *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno); return 0; }else if( x<4 ){ /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total ** number of bytes in fragments may not exceed 60. */ if( aData[hdr+7]>57 ) return 0; ................................................................................ ** for the portion used by the new allocation. */ put2byte(&aData[pc+2], x); } return &aData[pc + x]; } iAddr = pc; pc = get2byte(&aData[pc]); }while( pc ); return 0; } /* ** Allocate nByte bytes of space from within the B-Tree page passed ** as the first argument. Write into *pIdx the index into pPage->aData[] ................................................................................ */ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ u16 iPtr; /* Address of ptr to next freeblock */ u16 iFreeBlk; /* Address of the next freeblock */ u8 hdr; /* Page header size. 0 or 100 */ u8 nFrag = 0; /* Reduction in fragmentation */ u16 iOrigSize = iSize; /* Original value of iSize */ u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */ u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ assert( iStart<=iLast ); /* Overwrite deleted information with zeros when the secure_delete ** option is enabled */ if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ memset(&data[iStart], 0, iSize); } /* The list of freeblocks must be in ascending order. Find the ** spot on the list where iStart should be inserted. */ hdr = pPage->hdrOffset; iPtr = hdr + 1; if( data[iPtr+1]==0 && data[iPtr]==0 ){ ................................................................................ while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ if( iFreeBlk<iPtr+4 ){ if( iFreeBlk==0 ) break; return SQLITE_CORRUPT_PGNO(pPage->pgno); } iPtr = iFreeBlk; } if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno); assert( iFreeBlk>iPtr || iFreeBlk==0 ); /* At this point: ** iFreeBlk: First freeblock after iStart, or zero if none ** iPtr: The address of a pointer to iFreeBlk ** ** Check to see if iFreeBlk should be coalesced onto the end of iStart. ................................................................................ iSize = iEnd - iPtr; iStart = iPtr; } } if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno); data[hdr+7] -= nFrag; } if( iStart==get2byte(&data[hdr+5]) ){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another ** freelist entry */ if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); put2byte(&data[hdr+1], iFreeBlk); put2byte(&data[hdr+5], iEnd); }else{ /* Insert the new freeblock into the freelist */ put2byte(&data[iPtr], iStart); put2byte(&data[iStart], iFreeBlk); put2byte(&data[iStart+2], iSize); } pPage->nFree += iOrigSize; return SQLITE_OK; } /* ** Decode the flags byte (the first byte of the header) for a page ** and initialize fields of the MemPage structure accordingly. ................................................................................ ** error, return ((unsigned int)-1). */ static Pgno btreePagecount(BtShared *pBt){ return pBt->nPage; } SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ assert( sqlite3BtreeHoldsMutex(p) ); assert( ((p->pBt->nPage)&0x8000000)==0 ); return btreePagecount(p->pBt); } /* ** Get a page from the pager and initialize it. ** ** If pCur!=0 then the page is being fetched as part of a moveToChild() ................................................................................ MemPage **ppPage, /* Write the page pointer here */ BtCursor *pCur, /* Cursor to receive the page, or NULL */ int bReadOnly /* True for a read-only page */ ){ int rc; |